static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
		       unsigned *selector)
{
	const struct supply_info *info;
	struct tps6524x *hw;
	unsigned i;

	hw	= rdev_get_drvdata(rdev);
	info	= &supply_info[rdev_get_id(rdev)];

	if (info->flags & FIXED_VOLTAGE)
		return -EINVAL;

	for (i = 0; i < info->n_voltages; i++)
		if (min_uV <= info->voltages[i] &&
		    max_uV >= info->voltages[i])
			break;

	if (i >= info->n_voltages)
		i = info->n_voltages - 1;

	*selector = i;

	return write_field(hw, &info->voltage, i);
}
Exemplo n.º 2
0
static int handle_global_field(cJSON *json, struct nl_buffer *buffer,
		bool *globals_found)
{
	struct argp_option *opts;
	unsigned int i;
	int error;

	opts = get_global_opts();
	if (!opts)
		return -ENOMEM;

	for (i = 0; opts[i].name && opts[i].key; i++) {
		if (strcasecmp(json->string, opts[i].name) == 0) {
			error = write_field(json, &opts[i], buffer);
			if (globals_found[i])
				log_info("Note: I found multiple '%s' definitions.",
						opts[i].name);
			globals_found[i] = true;
			free(opts);
			return error;
		}
	}

	log_err("Unknown global configuration field: %s", json->string);
	free(opts);
	return -EINVAL;
}
Exemplo n.º 3
0
static void write_fields( FILE *f, const save_field_t *fields, void *base ) {
    const save_field_t *field;

    for( field = fields; field->type; field++ ) {
        write_field( f, field, base );
    }
}
Exemplo n.º 4
0
static int write_record(avro_writer_t out, const struct avro_record_schema_t *record)
{
	int rval;
	long i;

	check(rval, avro_write_str(out, "{\"type\":\"record\",\"name\":\""));
	check(rval, avro_write_str(out, record->name));
	check(rval, avro_write_str(out, "\","));
	if (record->space) {
		check(rval, avro_write_str(out, "\"namespace\":\""));
		check(rval, avro_write_str(out, record->space));
		check(rval, avro_write_str(out, "\","));
	}
	check(rval, avro_write_str(out, "\"fields\":["));
	for (i = 0; i < record->fields->num_entries; i++) {
		union {
			st_data_t data;
			struct avro_record_field_t *field;
		} val;
		st_lookup(record->fields, i, &val.data);
		if (i) {
			check(rval, avro_write_str(out, ","));
		}
		check(rval, write_field(out, val.field));
	}
	return avro_write_str(out, "]}");
}
Exemplo n.º 5
0
static int disable_supply(struct regulator_dev *rdev)
{
	const struct supply_info *info;
	struct tps6524x *hw;

	hw	= rdev_get_drvdata(rdev);
	info	= &supply_info[rdev_get_id(rdev)];

	return write_field(hw, &info->enable, 0);
}
Exemplo n.º 6
0
/* Iterate over the given php zval** and transform into protobuf compatible values.
   Write those into the given protobuf message pointer. */
int
php_message (const ProtobufCMessage* message, zval* val)
{
    HashPosition pos;
    HashTable* hash_table = Z_ARRVAL_P(val);
    zval** data;
    char* key;
    int i, j, key_len;
    long index;

    // check if all required fields are existent in the given php array.
    // NULL default values if not
    for (j=0 ; j < message->descriptor->n_fields ; ++j) {
        const ProtobufCFieldDescriptor* tmp_field = message->descriptor->fields + j;

        if (! zend_symtable_exists(hash_table, (char*)tmp_field->name,
                strlen((char*)(tmp_field->name)) + 1)) {
            if (tmp_field->label == PROTOBUF_C_LABEL_REQUIRED) {
                zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC,
                    "cannot find required field '%s'", tmp_field->name);
                return 1;
            } else {
                null_field(message, tmp_field);
            }
        }
    }

    // copy php values to proto
    zend_hash_internal_pointer_reset_ex(hash_table, &pos);
    for (;; zend_hash_move_forward_ex(hash_table, &pos)) {
        zend_hash_get_current_data_ex(hash_table, (void**)&data, &pos);

        i = zend_hash_get_current_key_ex(hash_table, &key, &key_len, &index, 0, &pos);
        
        if (i == HASH_KEY_NON_EXISTANT) {
            break;
        } else if (i == HASH_KEY_IS_STRING) {

            const ProtobufCFieldDescriptor* field = find_field(message, key);
            if (field == NULL)
                continue;

            if (write_field(message, field, data) != 0) {
                zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC,
                    "unable to pack field '%s'", field->name);
                return 1;
            }
        }
    }

    return 0;
}
Exemplo n.º 7
0
static int set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
{
	const struct supply_info *info;
	struct tps6524x *hw;

	hw	= rdev_get_drvdata(rdev);
	info	= &supply_info[rdev_get_id(rdev)];

	if (info->flags & FIXED_VOLTAGE)
		return -EINVAL;

	return write_field(hw, &info->voltage, selector);
}
Exemplo n.º 8
0
void main(int argc, char *argv[]) {
    void error_print();

    int i,j;
    double gain, i_sat, base, ss, intensity, dx,dx2;
    long ik1;



    /* Processing the command line argument  */

    if (argc != 4) {
        error_print(argv[0]);
        exit(1);
    }
    /* reading the data from a command line */
    sscanf(argv[1],"%le", &gain);
    sscanf(argv[2],"%le",&base);
    sscanf(argv[3],"%le",&i_sat);

    read_field();
    dx =field.size/(field.number);
    dx2 = dx*dx;


    ik1=0;
    for (i=1; i<=field.number ; i++) {
        for (j=1; j<=field.number ; j++) {
            intensity=(field.real[ik1]*field.real[ik1]+\
                       field.imaginary[ik1]*field.imaginary[ik1]);


            ss=exp(base*(gain/(1.+(intensity/i_sat))));

            field.real[ik1] *= ss;
            field.imaginary[ik1] *= ss;
            ik1++;
        }

    }
    write_field();


}
Exemplo n.º 9
0
static int set_current_limit(struct regulator_dev *rdev, int min_uA,
			     int max_uA)
{
	const struct supply_info *info;
	struct tps6524x *hw;
	int i;

	hw	= rdev_get_drvdata(rdev);
	info	= &supply_info[rdev_get_id(rdev)];

	if (info->n_ilimsels == 1)
		return -EINVAL;

	for (i = info->n_ilimsels - 1; i >= 0; i--) {
		if (min_uA <= info->ilimsels[i] &&
		    max_uA >= info->ilimsels[i])
			return write_field(hw, &info->ilimsel, i);
	}

	return -EINVAL;
}
Exemplo n.º 10
0
static int set_current_limit(struct regulator_dev *rdev, int min_uA,
			     int max_uA)
{
	const struct supply_info *info;
	struct tps6524x *hw;
	int i;

	hw	= rdev_get_drvdata(rdev);
	info	= &supply_info[rdev_get_id(rdev)];

	if (info->flags & FIXED_ILIMSEL)
		return -EINVAL;

	for (i = 0; i < info->n_ilimsels; i++)
		if (min_uA <= info->ilimsels[i] &&
		    max_uA >= info->ilimsels[i])
			break;

	if (i >= info->n_ilimsels)
		return -EINVAL;

	return write_field(hw, &info->ilimsel, i);
}
Exemplo n.º 11
0
void write_record_CSV(FILE *out, const struct AddressAppInfo *aai, 
        const struct Address *addr, const int attribute, 
        const int category) {
        
	int j;
	char buffer[16];

	if (augment && (category || addr->showPhone)) {
		write_field(out,
				aai->category.name[category],
				term_semi);
		write_field(out,
				aai->phoneLabels[addr->phoneLabel[addr->showPhone]],
				term_semi);
	}

	for (j = 0; j < 19; j++) {
		if (addr->entry[realentry[j]]) {
			if (augment && (j >= 4) && (j <= 8)) {
				write_field(out,
						aai->phoneLabels[addr->phoneLabel
								[j - 4]], term_semi);
			}
			write_field(out, addr->entry[realentry[j]],
					tabledelim);
		} else {
			write_field(out, "", tabledelim);
		}
	}

	snprintf(buffer, sizeof(buffer), "%d", (attribute & dlpRecAttrSecret) ? 1 : 0);
	write_field(out, buffer, tabledelim);

	write_field(out,
		aai->category.name[category],
		term_newline);
}
Exemplo n.º 12
0
void main(int argc, char *argv[]){
    void error_print();

    int i,j,i2;
    double sx,sy,dx,x,y, x0,y0,x_shift, y_shift, angle,cc,ss;
    long ik1;



    /* Processing the command line argument  */

    if (argc<2 || argc >6){
        error_print(argv[0]);
        exit(1);
    }
    /* reading the data from a command line */
    sscanf(argv[1],"%le",&sy);
    sx=sy;
    x_shift=y_shift=angle=0.;
    if(argc == 3) sscanf(argv[2],"%le",&sx);
    if(argc == 4) {
        sscanf(argv[2],"%le",&sx);
        sscanf(argv[3],"%le",&y_shift);
    }
    if(argc == 5){
        sscanf(argv[2],"%le",&sx);
        sscanf(argv[3],"%le",&y_shift); 
        sscanf(argv[4],"%le",&x_shift);
    }
     if(argc == 6){
        sscanf(argv[2],"%le",&sx);
        sscanf(argv[3],"%le",&y_shift); 
        sscanf(argv[4],"%le",&x_shift);
	sscanf(argv[5],"%le",&angle);
	angle *= -Pi2/360.;
    }
    read_field();

    dx =field.size/(field.number);
    i2=field.number/2+1;

    /* Cuttitng the aperture      */

    for (i=1;i<=field.number ;i++)
        for (j=1;j<=field.number ;j++){

            ik1=(i-1)*field.number+j-1;
            x0=(i-i2)*dx-x_shift;
            y0=(j-i2)*dx-y_shift;

	    cc=cos(angle);
	    ss=sin(angle);
	    x=x0*cc+y0*ss;
	    y=-x0*ss+y0*cc;  
            if(fabs(x) > sx/2. || fabs(y) > sy/2. ) {
                field.real[ik1]=0.;
                field.imaginary[ik1]=0.;
            }

        }
    write_field();


}
Exemplo n.º 13
0
int main(int argc, char *argv[]) 
{
  // Set directory structure
  directory_init(argc, argv);

  printf("Initializing...\n"); 
  fflush(stdout);
  // Read input file
  main_read_input();

  // Read and sort output directory for finding files within our time limits
  init_files();

  // Initialize domain and flow arrays
  domain_init(); 

  // Create output directory
  create_output();
  get_sigfigs();

  // Pull initial time step
  tt = 0;
  cgns_fill();

  // Find min and max and set up bins
  minmax(&min_vf, &max_vf, volume_fraction);
  minmax(&min_wp, &max_wp, part_w);
  minmax(&min_ke, &max_ke, part_ke);
  bin_init(min_vf, max_vf, &dBin_vf, &binStart_vf, &binEnd_vf);
  bin_init(min_wp, max_wp, &dBin_wp, &binStart_wp, &binEnd_wp);
  bin_init(min_ke, max_ke, &dBin_ke, &binStart_ke, &binEnd_ke);

  #ifdef DEBUG
    printf("  Bin Start (vf) = %lf\n", binStart_vf);
    printf("  Min (vf) = %lf\n", min_vf);
    printf("  dBin (vf) = %lf\n", dBin_vf);
    printf("  Max (vf) = %lf\n", max_vf);
    printf("  Bin End (vf) = %lf\n", binEnd_vf);
  #endif
    printf("  Bin Start (ke) = %lf\n", binStart_ke);
    printf("  Min (ke) = %lf\n", min_ke);
    printf("  dBin (ke) = %lf\n", dBin_ke);
    printf("  Max (ke) = %lf\n", max_ke);
    printf("  Bin End (ke) = %lf\n", binEnd_ke);

  // normalization for means
  double norm = 1./(dom.Gcc.s3 * nFiles);

  // Loop over time and bin
  printf("Looping...\n"); 
  fflush(stdout);
  int ind, ind_vf, ind_wp;

  for (tt = 0; tt < nFiles; tt++) {
    printf("  Timestep = %d of %d\n", tt+1, nFiles);
    fflush(stdout);
    // Fill data from cgns file
    cgns_fill();

    // Loop over space
    for (int cc = 0; cc < dom.Gcc.s3; cc++) {
      /* Volume Fraction */
      mean_vf += norm*volume_fraction[cc];
      // calculate index
      ind = (volume_fraction[cc] - binStart_vf)/dBin_vf;
      // if ind < 0, make it zero
      // if ind > nBins + 1, make it nBins +1
      ind = ind*(ind >= 0);         
      ind = ind*(ind <= (nBins + 1)) + (nBins + 1)*(ind > (nBins + 1));
      histogram_vf[ind]++;

      ind_vf = ind;

      /* Part Wp */
      mean_wp += norm*part_w[cc];
      ind = (part_w[cc] - binStart_wp)/dBin_wp;
      ind = ind*(ind >= 0);         
      ind = ind*(ind <= (nBins + 1)) + (nBins + 1)*(ind > (nBins + 1));
      histogram_wp[ind]++;

      ind_wp = ind;

      /* Bivariate */
      bihistogram_vf_wp[ind_wp + (nBins + 2)*ind_vf]++;

      /* Kinetic Energy */
      mean_ke += norm*part_ke[cc];
      ind = (part_ke[cc] - binStart_ke)/dBin_ke;
      ind = ind*(ind >= 0);         
      ind = ind*(ind <= (nBins + 1)) + (nBins + 1)*(ind > (nBins + 1));
      histogram_ke[ind]++;
    }

    // keep track of min max mean std for ALL files?
    // have bin padding as an input parameter?

  }
  // write to file
  write_field();

  // Free and exit
  printf("Done!\n");
  free_vars();
  return EXIT_SUCCESS;
}
Exemplo n.º 14
0
int write_file(FILE *out, int sd, int db, struct AddressAppInfo *aai, int human) {
	int 	i,
		j,
		attribute,
		category;
	struct 	Address addr;
	pi_buffer_t *buf;

	int count = 0;
	const char *progress = "   Writing Palm Address Book entries to file... ";

	if (!human) {
		/* Print out the header and fields with fields intact. Note we
		'ignore' the last field (Private flag) and print our own here, so
		we don't have to chop off the trailing comma at the end. Hacky. */
		fprintf(out, "# ");
		for (j = 0; j < 21; j++) {
			write_field(out, tableheads[j],
				j<20 ? tabledelim : term_newline);
		}
		if (augment) {
			fprintf(out,"### This in an augmented (non-standard) CSV file.\n");
		}
	}

	if (!plu_quiet) {
		printf("%s",progress);
		fflush(stdout);
	}

	buf = pi_buffer_new (0xffff);
	for (i = 0;
	     (j =
	      dlp_ReadRecordByIndex(sd, db, i, buf, 0,
				    &attribute, &category)) >= 0;
	     i++) {


		if (attribute & dlpRecAttrDeleted)
			continue;
		unpack_Address(&addr, buf, address_v1);

		if (!human) {
			write_record_CSV(out,aai,&addr,attribute,category);
		} else {
			write_record_human(aai,&addr,category);
		}


		++count;
		if (!plu_quiet) {
			printf("\r%s%d",progress,count);
			fflush(stdout);
		}
	}
	pi_buffer_free (buf);

	if (!plu_quiet) {
		printf("\r%s%d\n   Done.\n",progress,count);
		fflush(stdout);
	}
	return 0;
}
Exemplo n.º 15
0
/*!
	Writes a field defined on the patch.

	\param name is the name of the field
	\param type is the type of the field, a field can be defined either
	on the vertices of on the cells
	\param values is a vector with the values of the field
*/
void Patch::write_field(std::string name, int type, std::vector<double> values)
{
	write_field(get_name(), name, type, values);
}
Exemplo n.º 16
0
int main(int argc, char *argv[]) {
  double *int_depth, *lay_depth;
  int nvar=0, n_tname = 0, n, m, i, j, k, lev, v, num_files = 0;
  size_t nx, ny, nxy, nz;
  int verbose = 0;
  int status;
  size_t nlay, nint;
  double st_eta[2], st_var[2];
  double *eta = NULL, *var_out = NULL, *var_in = NULL, *ev = NULL;
  double *elc = NULL;
//  double elc[100], depths[100];
  char var_names[MAX_VARS][NC_MAX_NAME], eta_name[NC_MAX_NAME];
  double EPSILON = 1.0e-10;
  double missing = -1.0e34;
  char time_names[2][NC_MAX_NAME], depth_names[2][NC_MAX_NAME];

  char depth_file[FILE_NAME_SZ], in_file[MAX_FILES][FILE_NAME_SZ], out_file[FILE_NAME_SZ];
  char arglist[2000];

  
  // The following block interprets the input fields.
  {
    if (argc < 6) {
      printf("%s requires at least 5 arguments (# = %d):\n\n"
          "useage:\n%s -d'Depth_file' -V:'variable_names'[,'vn2',...] -e'Eta_name' variables\n"
          "\t-T:'Time_varable_name1,Time_varable_name2' -o'Output_file' 'Input_file_name[s]'\n"
          "\nOptions:\n\t-v\t\t Verbose mode"
           "\n\t-z:'Z-center_name,Z-edge_name'"
         "\nvariables:\n\tVariable names from input file.\n",
          argv[0],argc-1,argv[0]);
      return -1;
    }
    
    strcpy(arglist,argv[0]);
    for (n=1;n<argc;n++) {strcat(arglist," "); strcat(arglist,argv[n]);}

    for (n=1;n<argc;n++) if (strcmp(argv[n],"-v")==0) {
      verbose = 1; printf("\nUsing verbose mode.\n\n");
    }

    strcpy(depth_file,""); strcpy(out_file,"");
    for (n=0;n<MAX_FILES;n++) strcpy(in_file[n],"");
    strcpy(zc_name,"zt"); strcpy(ze_name,"zw");
    strcpy(eta_name,""); strcpy(time_names[0],""); strcpy(time_names[1],"");

    for (n=1;n<argc;n++) {
      size_t sz;
      // if (verbose) printf("Arg %d: %s\n",n,argv[n]);
      if (strcmp(argv[n],"-v")==0) continue;
      else if (strncmp(argv[n],"-z:",3)==0) {
        // PARSE FOR depth names.
        m = 3; sz = strlen(argv[n]);
        for (i=m;i<sz;i++) if (argv[n][i] == ',') {break;}
        strncpy(zc_name,&argv[n][m],i-m); zc_name[i-m] = '\0';
        // if (verbose) printf("\tTime name %d is %s.\n",n_tname,time_names[n_tname]);
        m = i+1;
        if (i<sz) {
          strncpy(ze_name,&argv[n][m],sz-m); ze_name[sz-m] = '\0';
        }
      }
      else if (strncmp(argv[n],"-d",2)==0) strcpy(depth_file,&argv[n][2]);
      else if (strncmp(argv[n],"-o",2)==0) strcpy(out_file,&argv[n][2]);
      else if (strncmp(argv[n],"-e",2)==0) strcpy(eta_name,&argv[n][2]);
      else if (strncmp(argv[n],"-V:",3)==0) {
        // PARSE FOR variable names.
        m = 3; sz = strlen(argv[n]);
        for (;;) {
          for (i=m;i<sz;i++) if (argv[n][i] == ',') {break;}
          strncpy(var_names[nvar],&argv[n][m],i-m);
          var_names[nvar][i-m] = '\0';
          // if (verbose) printf("\tVariable %d is %s.\n",nvar,var_names[nvar]);
          nvar++;
          if (i==sz) break;
          m = i+1;
        }
      }
      else if (strncmp(argv[n],"-T:",3)==0) {
        // PARSE FOR time names.
        m = 3; sz = strlen(argv[n]);
        for (;;) {
          for (i=m;i<sz;i++) if (argv[n][i] == ',') {break;}
          strncpy(time_names[n_tname],&argv[n][m],i-m);
          time_names[n_tname][i-m] = '\0';
          // if (verbose) printf("\tTime name %d is %s.\n",n_tname,time_names[n_tname]);
          n_tname++;
          if (i==sz) break;
          m = i+1;
        }
      }
      else if (strncmp(argv[n],"-",1)==0)
        printf("Unrecognized argument %s.\n",argv[n]);
      else {
        // Add input file name.
        if (num_files >= MAX_FILES)
          printf("Unable to add input file %s, because %d files are already in use.\n"
                 "Increase MAX_FILES in %s.c.\n",argv[n],num_files,argv[0]);
        strcpy(in_file[num_files],argv[n]);
        // if (verbose) printf("Adding input file %d with name %s.\n",num_files,in_file[num_files]);
        num_files++;
      }
    }

    if (strlen(depth_file) == 0) {
      printf("Depth file name must be specified as -dDEPTH_FILE_NAME\n");
      exit(-1);
    }
    if (num_files == 0) {
      printf("At least one input file name must be specified.\n");
      exit(-1);
    }
    if (strlen(out_file) == 0) {
      printf("Output file name must be specified as -oOUTPUT_FILE_NAME\n");
      exit(-1);
    }
    if (strlen(eta_name) == 0) {
      printf("Interface height variable name must be specified as -eETA_NAME\n");
      exit(-1);
    }
    if (nvar < 1) {
      printf("At least 1 variable must be specified.\n");
      exit(-1);
    }
  }
      
  strcpy(depth_names[0],zc_name);
  strcpy(depth_names[1],ze_name);
  //  get_vertical_grid(...);
  if (verbose) printf("\tGet depths from %s.\n",depth_file);
  get_depths(depth_file, depth_names, &lay_depth, &int_depth, &nz);

  
//  if (verbose) printf("Read eta as %s from %s.\n",eta_name,in_file);
//  read_eta(in_file,eta_name,&eta,&nlay);
  
  // Create the new NetCDF file.
  {
    if (verbose) printf("\tPrepare %s.\n",out_file);
    write_output(out_file,in_file,depth_file,
                 nz,var_names,time_names,depth_names,&nvar,arglist);
  }

  // Allocate space for the depth space variables.
  // if (verbose) printf("Read eta.\n");
  status = read_field(0,0,eta_name,&eta,&nint,&nx,&ny, st_eta);
  if (status != 0) {
    printf("ERROR: Unsuccessful in reading %s from %s.\n",eta_name,in_file[0]);
    exit(-1);
  }
  if (verbose) printf("\tEta %s starts at %g %g.\n",eta_name,st_eta[0],st_eta[1]);
  nxy = nx*ny;
  nlay = nint-1;

  if (verbose) printf("\tAllocating space for output variables.\n");
  var_out = (double *) calloc((size_t) (nz*nxy), sizeof(double));
  ev = (double *) calloc((size_t) nint, sizeof(double));
  elc = (double *) calloc((size_t) nint, sizeof(double));
  if (verbose) printf("\tDone with allocations.\n");
  

  for (lev=0;;lev++) {
    size_t junk, nlv, nxv, nyv, nxyv;
  
    if (verbose) printf("\tWorking on time level %d.\n",lev);
    
    if (lev>0) {
      // if (verbose) printf("Read %s for time %d.\n",eta_name,lev);
      status = read_field(0, lev, eta_name, &eta, &junk, &junk, &junk, st_eta);
      // if (verbose) printf("Done reading %s for time %d.\n",eta_name,lev);
    }
    if (status != 0) break;
    for (k=nint-1;k>=0;k--) for (i=0;i<nxy;i++) eta[k*nxy+i] -= eta[i];

    for (v=0;v<nvar;v++) {
            // This assumes that the missing value is -1e34.
      double missing_value = -1.0e34;
      int I, grid = 0;
      if ((lev>0) && static_var[v]) break;
     // if (verbose) printf("Read %s for time %d.\n",var_names[v],lev);
      status = read_field(var_file[v], lev, var_names[v], &var_in, &nlv, &nxv, &nyv, st_var);
      nxyv = nxv*nyv;
      if (status != 0) break;
     // if (verbose) printf("Done reading %s for time %d - starts at %g %g.\n",
     //   var_names[v],lev,st_var[0],st_var[1]);
      if (nlv != nlay) printf("Mismatch of layers %d vs expected %d.\n",(int) nlv, (int) nlay);

      if ((st_var[0] == st_eta[0]) && (st_var[1] == st_eta[1])) { grid = 0;
        if (verbose && (lev==0)) printf("\t%s is on the h-grid.\n",var_names[v]);
        if ((nyv != ny) || (nxv != nx)) {
          printf("h-grid variable %s is not same size as %s (%d x %d) vs (%d x %d).\n",
              var_names[v],eta_name,(int)nyv,(int)ny,(int)nxv,(int)nx);
          exit(-1);
        }
      }
      else if ((st_var[0] == st_eta[0]) && (st_var[1] != st_eta[1])) { grid = 1;
        if (verbose && (lev==0)) printf("\t%s is on the u-grid.\n",var_names[v]);
        if ((nyv != ny) || (abs((nxv-nx))>1)) {
          printf("u-grid variable %s is not consistent size with %s (%d x %d) vs (%d x %d).\n",
              var_names[v],eta_name,(int)nyv,(int)nxv,(int)ny,(int)nx);
          exit(-1);
        }
   //     printf("%s is on the u-grid.  No accomodation has yet been made for this grid.\n"
      }
      else if ((st_var[1] == st_eta[1]) && (st_var[0] != st_eta[0])) { grid = 2;
        if (verbose && (lev==0)) printf("\t%s is on the v-grid.\n",var_names[v]);
        if ((nxv != nx) || (abs((nyv-ny))>1)) {
          printf("v-grid variable %s is not consistent size with %s (%d x %d) vs (%d x %d).\n",
              var_names[v],eta_name,(int)nyv,(int)nxv,(int)ny,(int)nx);
          exit(-1);
        }
   //     printf("%s is on the v-grid.  No accomodation has yet been made for this grid.\n"
      } else {
        printf("%s is on the q-grid.  No accomodation has yet been made for this grid.\n"
               "Start locations: %g, %g vs %g, %g. Delta %g, %g\n",var_names[v],st_var[1],st_var[0],
                st_eta[1],st_eta[0],st_var[1]-st_eta[1],st_var[0]-st_eta[0]);
        exit(-1);
      }

/*      { int K;
        for (K=0;K<nz;K++) depths[K] = lay_depth[K]; 
      } */
      
      for (j=0;j<nyv;j++) for (i=0;i<nxv;i++) {
        I = i + nxv*j;
        // Interpolate interface height onto the variable's grid.
        if (grid == 0) {
          for (k=0;k<nint;k++) ev[k] = eta[k*nxy+I];
        } if (grid == 1) {
          if (st_var[1] < st_eta[1]) {
            if (i==0) {
              if (nx!=nxv) for (k=0;k<nint;k++) ev[k] = eta[k*nxy+j*nx];
              else for (k=0;k<nint;k++) ev[k] = 0.5*(eta[k*nxy+j*nx]+eta[k*nxy+j*nx+nx-1]);
            }
            else if ((i==nxv-1)&&(nxv>nx)) {
              for (k=0;k<nint;k++) ev[k] = eta[k*nxy+j*nx+i-1];
            }
            else for (k=0;k<nint;k++) ev[k] = 0.5*(eta[k*nxy+j*nx+i]+eta[k*nxy+j*nx+i-1]);
          } else {
            if (i==nx-1) for (k=0;k<nint;k++) ev[k] = 0.5*(eta[k*nxy+j*nx+i]+eta[k*nxy+j*nx]);
            else for (k=0;k<nint;k++) ev[k] = 0.5*(eta[k*nxy+j*nx+i]+eta[k*nxy+j*nx+i+1]);
          }
        } else if (grid == 2) {
          if (st_var[0] < st_eta[0]) {
            if (j==0) {
              if (ny!=nyv) for (k=0;k<nint;k++) ev[k] = eta[k*nxy+i];
              else for (k=0;k<nint;k++) ev[k] = 0.5*(eta[k*nxy+j*nx+i]+eta[k*nxy+(ny-1)*nx+i]);
            }
            else if ((j==nyv-1)&&(nyv>ny)) {
              for (k=0;k<nint;k++) ev[k] = eta[k*nxy+(j-1)*nx+i];
            }
            else for (k=0;k<nint;k++) ev[k] = 0.5*(eta[k*nxy+j*nx+i]+eta[k*nxy+(j-1)*nx+i]);
          } else {
            if (j==ny-1) for (k=0;k<nint;k++) ev[k] = 0.5*(eta[k*nxy+j*nx+i]+eta[k*nxy+i]);
            else for (k=0;k<nint;k++) ev[k] = 0.5*(eta[k*nxy+j*nx+i]+eta[k*nxy+(j+1)*nx+i]);
          }
        }
        
        {
          int K, ktop=0, kbot=0;
          double z_sbl = 0.0, z_bbl = 0.0;
//          double e_bot;
          for (k=0;k<nlay;k++) elc[k] = 0.5*(ev[k]+ev[k+1]);
          for (k=0;k<nlay;k++) {
            if (((ev[0]-elc[k]) > 2.0*nlay*EPSILON) && (var_in[k*nxyv+I] != missing_value))
              {ktop = k; z_sbl = elc[k]; break;}
          }
          for (k=nlay-1;k>=0;k--) {
            if (((elc[k]-ev[nint-1]) > 2.0*nlay*EPSILON) && (var_in[k*nxyv+I] != missing_value))
              {kbot = k; z_bbl = elc[k]; break;}
          }

          // Fill in massless interior layers with values from above.
          for (k=ktop+1;k<kbot;k++) {
            if ((ev[k]-ev[k+1]) < 2.0*EPSILON) var_in[k*nxyv+I] = var_in[(k-1)*nxyv+I];
            if (var_in[k*nxyv+I] == missing_value) var_in[k*nxyv+I] = var_in[(k-1)*nxyv+I];
          }
          // Interpolate var into depth space.
          k=ktop;
//          if (z_bbl < 0.0)
//            e_bot = ev[nint-1];
          for (K=0;K<nz;K++) {
            if (lay_depth[K] > z_sbl)
              var_out[K*nxyv+I] = var_in[ktop*nxyv+I];
            else if (lay_depth[K] < ev[nint-1])
              var_out[K*nxyv+I] = missing;
            else if
              (lay_depth[K] < z_bbl) var_out[K*nxyv+I] = var_in[kbot*nxyv+I];
            else {
              while ((lay_depth[K] < elc[k]) && (k <= kbot)) k++;

              if ((lay_depth[K] >= elc[k]) && (lay_depth[K] <= elc[k-1])) {
                var_out[K*nxyv+I] = var_in[k*nxyv+I];
                /**/
                if (fabs(elc[k-1]-elc[k]) > EPSILON)
                  var_out[K*nxyv+I] += (var_in[(k-1)*nxyv+I] - var_in[k*nxyv+I]) *
                    ((lay_depth[K] - elc[k]) / (elc[k-1]-elc[k]));
                   /* */
              } else {
                printf("Unexpected error: k = %d, ktop = %d, kbot = %d, Depth %g is not between %g and %g.\n",
                        k,ktop,kbot,lay_depth[K],elc[k-1],elc[k]);
              }
            }

          }
        }
        
      }
      
      // if (verbose) printf("Done interpolating %s for time %d.\n",var_names[v],lev);
      write_field(lev,v,var_out);
      // if (verbose) printf("Done writing %s for time %d.\n",var_names[v],lev);
    }

    // if (verbose) printf("Start copying time at %d.\n",lev);
    copy_time_vals(lev);
    // if (verbose) printf("Done copying time at %d.\n",lev);
    
    // status = nc_sync(ncOutid);
    // if (status != NC_NOERR) handle_error(status,out_file,status);
  }

  nc_close(ncOutid);
  if (verbose) printf("Done: successfully created %s.\n",out_file);
  for (i=0;i<num_files;i++) if (ncInid[i] >= 0) nc_close(ncInid[i]);

}
Exemplo n.º 17
0
void write_grid_file(void) {
/*    The following subroutine saves the depth, reduced gravity of    */
/*  each interface, the potential density of each layer, and the      */
/*  Coriolis parameter.  A variety of metric terms are written to a   */
/*  separate file.                                                    */
  char filename[40];           /* The file name of the save file.     */
  char filepath[120];          /* The path (dir/file) to the file.    */
  int i, j, cdfid, timeid;
  size_t err = 1;

  struct varcdfinfo varinfo[10];
/*   vardesc is a structure defined in HIM_io.h.   The elements of    */
/* this structure, in order, are: (1) the variable name for the NetCDF*/
/* file; (2) the variable's long name; (3) a character indicating the */
/* horizontal grid, which may be '1' (column), 'h', 'q', 'u', or 'v', */
/* for the corresponding C-grid variable; (4) a character indicating  */
/* the vertical grid, which may be 'L' (layer), 'i' (interface),      */
/* '2' (mixed-layers), or '1' (no vertical location); (5) a character */
/* indicating the time levels of the field, which may be 's' (snap-   */
/* shot), 'a' (average between snapshots), 'm' (monthly average), or  */
/* '1' (no time variation); (6) the variable's units; and (7) a       */
/* character indicating the size in memory to write, which may be     */
/* 'd' (8-byte) or 'f' (4-byte).                                      */
  vardesc vars[4] = {
    {"D","Basin Depth",'h','1','1',"meter", 'd'},
    {"g","Reduced gravity",'1','L','1',"meter second-2", 'd'},
    {"R","Target Potential Density",'1','L','1',"kilogram meter-3", 'd'},
    {"f","Coriolis Parameter",'q','1','1',"second-1", 'd'}
  };

  sprintf(filename,"D.%d.%d.%d",NXTOT,NYTOT,NZ);
  strcpy(filepath, directory);
  strcat(filepath, filename);

  create_file(filepath, vars, 4, &cdfid, &timeid, varinfo);
  err *= write_field(cdfid, vars[0], varinfo[0], 0, D[0]);
  err *= write_field(cdfid, vars[1], varinfo[1], 0, g);
  err *= write_field(cdfid, vars[2], varinfo[2], 0, Rlay);
  err *= write_field(cdfid, vars[3], varinfo[3], 0, f[0]);

  close_file(&cdfid);
  if (err == 0)
    printf("Problems saving general parameters.\n");

  {
/* ### REVISIT THIS PART OF THE ROUTINE AFTER METRICS... ### */
    double out[NYMEM][NXMEM];     /* An array for output.  */
    extern double hmask[NYMEM][NXMEM];

    vardesc vars2[10]={
      {"geolatb","latitude at q points",'q','1','1',"degree",'d'},
      {"geolonb","longitude at q points",'q','1','1',"degree",'d'},
      {"wet", "land or ocean?", 'h','1','1',"none",'d'},
      {"geolat", "latitude at h points", 'h','1','1',"degree",'d'},
      {"geolon","longitude at h points",'h','1','1',"degree",'d'},
      {"dxh","Zonal grid spacing at h points",'h','1','1',"m",'d'},
      {"dxq","Zonal grid spacing at q points",'q','1','1',"m",'d'},
      {"dyh","Meridional grid spacing at h points",'h','1','1',"m",'d'},
      {"dyq","Meridional grid spacing at q points",'q','1','1',"m",'d'},
      {"Ah","Area of h cells",'h','1','1',"m2",'d'},
    };

    sprintf(filename,"grid.%d.%d",NXTOT,NYTOT);
    strcpy(filepath, directory);
    strcat(filepath, filename);

    create_file(filepath, vars2, 10, &cdfid, &timeid, varinfo);
    err *= write_field(cdfid, vars2[0], varinfo[0], 0, geolatq[0]);
    err *= write_field(cdfid, vars2[1], varinfo[1], 0, geolonq[0]);
    err *= write_field(cdfid, vars2[2], varinfo[2], 0, hmask[0]);
    err *= write_field(cdfid, vars2[3], varinfo[3], 0, geolath[0]);
    err *= write_field(cdfid, vars2[4], varinfo[4], 0, geolonh[0]);

    for (j=0;j<NYMEM;j++) for (i=0;i<NXMEM;i++) out[j][i]=DXh(j,i);
    err *= write_field(cdfid, vars2[5], varinfo[5], 0, out[0]);
    for (j=0;j<NYMEM;j++) for (i=0;i<NXMEM;i++) out[j][i]=DXq(j,i);
    err *= write_field(cdfid, vars2[6], varinfo[6], 0, out[0]);
    for (j=0;j<NYMEM;j++) for (i=0;i<NXMEM;i++) out[j][i]=DYh(j,i);
    err *= write_field(cdfid, vars2[7], varinfo[7], 0, out[0]);
    for (j=0;j<NYMEM;j++) for (i=0;i<NXMEM;i++) out[j][i]=DYq(j,i);
    err *= write_field(cdfid, vars2[8], varinfo[8], 0, out[0]);
    for (j=0;j<NYMEM;j++) for (i=0;i<NXMEM;i++) out[j][i]=DXDYh(j,i);
    err *= write_field(cdfid, vars2[9], varinfo[9], 0, out[0]);

    close_file(&cdfid);

    if (err == 0)
      printf("Problems saving latitude and longitude and wet.\n");
  }
}
Exemplo n.º 18
0
avro_schema_t avro_schema_string(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_STRING,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_bytes(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_BYTES,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_int(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_INT32,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_long(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_INT64,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_float(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_FLOAT,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_double(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_DOUBLE,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_boolean(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_BOOLEAN,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_null(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_NULL,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_fixed(const char *name, const int64_t size)
{
	struct avro_fixed_schema_t *fixed =
	    malloc(sizeof(struct avro_fixed_schema_t));
	if (!fixed) {
		return NULL;
	}
	if (!is_avro_id(name)) {
		return NULL;
	}
	fixed->name = strdup(name);
	fixed->size = size;
	avro_schema_init(&fixed->obj, AVRO_FIXED);
	return &fixed->obj;
}

avro_schema_t avro_schema_union(void)
{
	struct avro_union_schema_t *schema =
	    malloc(sizeof(struct avro_union_schema_t));
	if (!schema) {
		return NULL;
	}
	schema->branches = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
	if (!schema->branches) {
		free(schema);
		return NULL;
	}

	avro_schema_init(&schema->obj, AVRO_UNION);
	return &schema->obj;
}

int
avro_schema_union_append(const avro_schema_t union_schema,
			 const avro_schema_t schema)
{
	struct avro_union_schema_t *unionp;
	if (!union_schema || !schema || !is_avro_union(union_schema)) {
		return EINVAL;
	}
	unionp = avro_schema_to_union(union_schema);
	st_insert(unionp->branches, unionp->branches->num_entries,
		  (st_data_t) schema);
	avro_schema_incref(schema);
	return 0;
}

avro_schema_t avro_schema_array(const avro_schema_t items)
{
	struct avro_array_schema_t *array =
	    malloc(sizeof(struct avro_array_schema_t));
	if (!array) {
		return NULL;
	}
	array->items = avro_schema_incref(items);
	avro_schema_init(&array->obj, AVRO_ARRAY);
	return &array->obj;
}

avro_schema_t avro_schema_map(const avro_schema_t values)
{
	struct avro_map_schema_t *map =
	    malloc(sizeof(struct avro_map_schema_t));
	if (!map) {
		return NULL;
	}
	map->values = avro_schema_incref(values);
	avro_schema_init(&map->obj, AVRO_MAP);
	return &map->obj;
}

avro_schema_t avro_schema_enum(const char *name)
{
	struct avro_enum_schema_t *enump;

	if (!is_avro_id(name)) {
		return NULL;
	}
	enump = malloc(sizeof(struct avro_enum_schema_t));
	if (!enump) {
		return NULL;
	}
	enump->name = strdup(name);
	if (!enump->name) {
		free(enump);
		return NULL;
	}
	enump->symbols = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
	if (!enump->symbols) {
		free(enump->name);
		free(enump);
		return NULL;
	}
	enump->symbols_byname = st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
	if (!enump->symbols_byname) {
		st_free_table(enump->symbols);
		free(enump->name);
		free(enump);
		return NULL;
	}
	avro_schema_init(&enump->obj, AVRO_ENUM);
	return &enump->obj;
}

int
avro_schema_enum_symbol_append(const avro_schema_t enum_schema,
			       const char *symbol)
{
	struct avro_enum_schema_t *enump;
	char *sym;
	long idx;
	if (!enum_schema || !symbol || !is_avro_enum(enum_schema)) {
		return EINVAL;
	}
	enump = avro_schema_to_enum(enum_schema);
	sym = strdup(symbol);
	if (!sym) {
		return ENOMEM;
	}
	idx = enump->symbols->num_entries;
	st_insert(enump->symbols, (st_data_t) idx, (st_data_t) sym);
	st_insert(enump->symbols_byname, (st_data_t) sym, (st_data_t) idx);
	return 0;
}

int
avro_schema_record_field_append(const avro_schema_t record_schema,
				const char *field_name,
				const avro_schema_t field_schema)
{
	struct avro_record_schema_t *record;
	struct avro_record_field_t *new_field;
	if (!field_name || !field_schema || !is_avro_schema(record_schema)
	    || !is_avro_record(record_schema) || record_schema == field_schema
	    || !is_avro_id(field_name)) {
		return EINVAL;
	}
	record = avro_schema_to_record(record_schema);
	new_field = malloc(sizeof(struct avro_record_field_t));
	if (!new_field) {
		return ENOMEM;
	}
	new_field->name = strdup(field_name);
	new_field->type = avro_schema_incref(field_schema);
	st_insert(record->fields, record->fields->num_entries,
		  (st_data_t) new_field);
	st_insert(record->fields_byname, (st_data_t) new_field->name,
		  (st_data_t) new_field);
	return 0;
}

avro_schema_t avro_schema_record(const char *name, const char *space)
{
	struct avro_record_schema_t *record;
	if (!is_avro_id(name)) {
		return NULL;
	}
	record = malloc(sizeof(struct avro_record_schema_t));
	if (!record) {
		return NULL;
	}
	record->name = strdup(name);
	if (!record->name) {
		free(record);
		return NULL;
	}
	record->space = space ? strdup(space) : NULL;
	if (space && !record->space) {
		free(record->name);
		free(record);
		return NULL;
	}
	record->fields = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
	if (!record->fields) {
		if (record->space) {
			free(record->space);
		}
		free(record->name);
		free(record);
		return NULL;
	}
	record->fields_byname = st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
	if (!record->fields_byname) {
		st_free_table(record->fields);
		free(record->name);
		free(record);
		return NULL;
	}

	avro_schema_init(&record->obj, AVRO_RECORD);
	return &record->obj;
}

static int
save_named_schemas(const char *name, avro_schema_t schema,
		   avro_schema_error_t * error)
{
	st_table *st = (*error)->named_schemas;
	return st_insert(st, (st_data_t) name, (st_data_t) schema);
}

static avro_schema_t
find_named_schemas(const char *name, avro_schema_error_t * error)
{
	st_table *st = (*error)->named_schemas;
	union {
		avro_schema_t schema;
		st_data_t data;
	} val;
	if (st_lookup(st, (st_data_t) name, &(val.data))) {
		return val.schema;
	}
	return NULL;
};

avro_schema_t avro_schema_link(avro_schema_t to)
{
	struct avro_link_schema_t *link;
	if (!is_avro_named_type(to)) {
		return NULL;
	}
	link = malloc(sizeof(struct avro_link_schema_t));
	if (!link) {
		return NULL;
	}
	link->to = avro_schema_incref(to);
	avro_schema_init(&link->obj, AVRO_LINK);
	return &link->obj;
}

static int
avro_type_from_json_t(json_t * json, avro_type_t * type,
		      avro_schema_error_t * error, avro_schema_t * named_type)
{
	json_t *json_type;
	const char *type_str;

	if (json_is_array(json)) {
		*type = AVRO_UNION;
		return 0;
	} else if (json_is_object(json)) {
		json_type = json_object_get(json, "type");
	} else {
		json_type = json;
	}
	if (!json_is_string(json_type)) {
		return EINVAL;
	}
	type_str = json_string_value(json_type);
	if (!type_str) {
		return EINVAL;
	}
	/*
	 * TODO: gperf/re2c this 
	 */
	if (strcmp(type_str, "string") == 0) {
		*type = AVRO_STRING;
	} else if (strcmp(type_str, "bytes") == 0) {
		*type = AVRO_BYTES;
	} else if (strcmp(type_str, "int") == 0) {
		*type = AVRO_INT32;
	} else if (strcmp(type_str, "long") == 0) {
		*type = AVRO_INT64;
	} else if (strcmp(type_str, "float") == 0) {
		*type = AVRO_FLOAT;
	} else if (strcmp(type_str, "double") == 0) {
		*type = AVRO_DOUBLE;
	} else if (strcmp(type_str, "boolean") == 0) {
		*type = AVRO_BOOLEAN;
	} else if (strcmp(type_str, "null") == 0) {
		*type = AVRO_NULL;
	} else if (strcmp(type_str, "record") == 0) {
		*type = AVRO_RECORD;
	} else if (strcmp(type_str, "enum") == 0) {
		*type = AVRO_ENUM;
	} else if (strcmp(type_str, "array") == 0) {
		*type = AVRO_ARRAY;
	} else if (strcmp(type_str, "map") == 0) {
		*type = AVRO_MAP;
	} else if (strcmp(type_str, "fixed") == 0) {
		*type = AVRO_FIXED;
	} else if ((*named_type = find_named_schemas(type_str, error))) {
		*type = AVRO_LINK;
	} else {
		return EINVAL;
	}
	return 0;
}

static int
avro_schema_from_json_t(json_t * json, avro_schema_t * schema,
			avro_schema_error_t * error)
{
	avro_type_t type = 0;
	unsigned int i;
	avro_schema_t named_schemas = NULL;

	if (avro_type_from_json_t(json, &type, error, &named_schemas)) {
		return EINVAL;
	}

	switch (type) {
	case AVRO_LINK:
		*schema = avro_schema_link(named_schemas);
		break;

	case AVRO_STRING:
		*schema = avro_schema_string();
		break;

	case AVRO_BYTES:
		*schema = avro_schema_bytes();
		break;

	case AVRO_INT32:
		*schema = avro_schema_int();
		break;

	case AVRO_INT64:
		*schema = avro_schema_long();
		break;

	case AVRO_FLOAT:
		*schema = avro_schema_float();
		break;

	case AVRO_DOUBLE:
		*schema = avro_schema_double();
		break;

	case AVRO_BOOLEAN:
		*schema = avro_schema_boolean();
		break;

	case AVRO_NULL:
		*schema = avro_schema_null();
		break;

	case AVRO_RECORD:
		{
			json_t *json_name = json_object_get(json, "name");
			json_t *json_namespace =
			    json_object_get(json, "namespace");
			json_t *json_fields = json_object_get(json, "fields");
			unsigned int num_fields;
			const char *record_name;
			const char *record_namespace;

			if (!json_is_string(json_name)) {
				return EINVAL;
			}
			if (!json_is_array(json_fields)) {
				return EINVAL;
			}
			num_fields = json_array_size(json_fields);
			if (num_fields == 0) {
				return EINVAL;
			}
			record_name = json_string_value(json_name);
			if (!record_name) {
				return EINVAL;
			}
			if (json_is_string(json_namespace)) {
				record_namespace =
				    json_string_value(json_namespace);
			} else {
				record_namespace = NULL;
			}
			*schema =
			    avro_schema_record(record_name, record_namespace);
			if (save_named_schemas(record_name, *schema, error)) {
				return ENOMEM;
			}
			for (i = 0; i < num_fields; i++) {
				json_t *json_field =
				    json_array_get(json_fields, i);
				json_t *json_field_name;
				json_t *json_field_type;
				avro_schema_t json_field_type_schema;
				int field_rval;

				if (!json_is_object(json_field)) {
					avro_schema_decref(*schema);
					return EINVAL;
				}
				json_field_name =
				    json_object_get(json_field, "name");
				if (!json_field_name) {
					avro_schema_decref(*schema);
					return EINVAL;
				}
				json_field_type =
				    json_object_get(json_field, "type");
				if (!json_field_type) {
					avro_schema_decref(*schema);
					return EINVAL;
				}
				field_rval =
				    avro_schema_from_json_t(json_field_type,
							    &json_field_type_schema,
							    error);
				if (field_rval) {
					avro_schema_decref(*schema);
					return field_rval;
				}
				field_rval =
				    avro_schema_record_field_append(*schema,
								    json_string_value
								    (json_field_name),
								    json_field_type_schema);
				avro_schema_decref(json_field_type_schema);
				if (field_rval != 0) {
					avro_schema_decref(*schema);
					return field_rval;
				}
			}
		}
		break;

	case AVRO_ENUM:
		{
			json_t *json_name = json_object_get(json, "name");
			json_t *json_symbols = json_object_get(json, "symbols");
			const char *name;
			unsigned int num_symbols;

			if (!json_is_string(json_name)) {
				return EINVAL;
			}
			if (!json_is_array(json_symbols)) {
				return EINVAL;
			}

			name = json_string_value(json_name);
			if (!name) {
				return EINVAL;
			}
			num_symbols = json_array_size(json_symbols);
			if (num_symbols == 0) {
				return EINVAL;
			}
			*schema = avro_schema_enum(name);
			if (save_named_schemas(name, *schema, error)) {
				return ENOMEM;
			}
			for (i = 0; i < num_symbols; i++) {
				int enum_rval;
				json_t *json_symbol =
				    json_array_get(json_symbols, i);
				const char *symbol;
				if (!json_is_string(json_symbol)) {
					avro_schema_decref(*schema);
					return EINVAL;
				}
				symbol = json_string_value(json_symbol);
				enum_rval =
				    avro_schema_enum_symbol_append(*schema,
								   symbol);
				if (enum_rval != 0) {
					avro_schema_decref(*schema);
					return enum_rval;
				}
			}
		}
		break;

	case AVRO_ARRAY:
		{
			int items_rval;
			json_t *json_items = json_object_get(json, "items");
			avro_schema_t items_schema;
			if (!json_items) {
				return EINVAL;
			}
			items_rval =
			    avro_schema_from_json_t(json_items, &items_schema,
						    error);
			if (items_rval) {
				return items_rval;
			}
			*schema = avro_schema_array(items_schema);
			avro_schema_decref(items_schema);
		}
		break;

	case AVRO_MAP:
		{
			int values_rval;
			json_t *json_values = json_object_get(json, "values");
			avro_schema_t values_schema;

			if (!json_values) {
				return EINVAL;
			}
			values_rval =
			    avro_schema_from_json_t(json_values, &values_schema,
						    error);
			if (values_rval) {
				return values_rval;
			}
			*schema = avro_schema_map(values_schema);
			avro_schema_decref(values_schema);
		}
		break;

	case AVRO_UNION:
		{
			unsigned int num_schemas = json_array_size(json);
			avro_schema_t s;
			if (num_schemas == 0) {
				return EINVAL;
			}
			*schema = avro_schema_union();
			for (i = 0; i < num_schemas; i++) {
				int schema_rval;
				json_t *schema_json = json_array_get(json, i);
				if (!schema_json) {
					return EINVAL;
				}
				schema_rval =
				    avro_schema_from_json_t(schema_json, &s,
							    error);
				if (schema_rval != 0) {
					avro_schema_decref(*schema);
					return schema_rval;
				}
				schema_rval =
				    avro_schema_union_append(*schema, s);
				avro_schema_decref(s);
				if (schema_rval != 0) {
					avro_schema_decref(*schema);
					return schema_rval;
				}
			}
		}
		break;

	case AVRO_FIXED:
		{
			json_t *json_size = json_object_get(json, "size");
			json_t *json_name = json_object_get(json, "name");
			int size;
			const char *name;
			if (!json_is_integer(json_size)) {
				return EINVAL;
			}
			if (!json_is_string(json_name)) {
				return EINVAL;
			}
			size = json_integer_value(json_size);
			name = json_string_value(json_name);
			*schema = avro_schema_fixed(name, size);
			if (save_named_schemas(name, *schema, error)) {
				return ENOMEM;
			}
		}
		break;

	default:
		return EINVAL;
	}
	return 0;
}

int
avro_schema_from_json(const char *jsontext, const int32_t len,
		      avro_schema_t * schema, avro_schema_error_t * e)
{
	json_t *root;
	int rval = 0;
	avro_schema_error_t error;

	AVRO_UNUSED(len);

	if (!jsontext || !schema) {
		return EINVAL;
	}

	error = malloc(sizeof(struct avro_schema_error_t_));
	if (!error) {
		return ENOMEM;
	}
	*e = error;

	error->named_schemas = st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
	if (!error->named_schemas) {
		free(error);
		return ENOMEM;
	}

	root = json_loads(jsontext, &error->json_error);
	if (!root) {
		st_free_table(error->named_schemas);
		free(error);
		return EINVAL;
	}

	/*
	 * json_dumpf(root, stderr, 0); 
	 */
	rval = avro_schema_from_json_t(root, schema, e);
	json_decref(root);
	st_free_table(error->named_schemas);
	if (rval == 0) {
		/* no need for an error return */
		free(error);
	}
	return rval;
}

avro_schema_t avro_schema_copy(avro_schema_t schema)
{
	long i;
	avro_schema_t new_schema = NULL;
	if (!schema) {
		return NULL;
	}
	switch (avro_typeof(schema)) {
	case AVRO_STRING:
	case AVRO_BYTES:
	case AVRO_INT32:
	case AVRO_INT64:
	case AVRO_FLOAT:
	case AVRO_DOUBLE:
	case AVRO_BOOLEAN:
	case AVRO_NULL:
		/*
		 * No need to copy primitives since they're static 
		 */
		new_schema = schema;
		break;

	case AVRO_RECORD:
		{
			struct avro_record_schema_t *record_schema =
			    avro_schema_to_record(schema);
			new_schema =
			    avro_schema_record(record_schema->name,
					       record_schema->space);
			for (i = 0; i < record_schema->fields->num_entries; i++) {
				union {
					st_data_t data;
					struct avro_record_field_t *field;
				} val;
				st_lookup(record_schema->fields, i, &val.data);
				avro_schema_t type_copy =
				    avro_schema_copy(val.field->type);
				avro_schema_record_field_append(new_schema,
								val.field->name,
								type_copy);
			}
		}
		break;

	case AVRO_ENUM:
		{
			struct avro_enum_schema_t *enum_schema =
			    avro_schema_to_enum(schema);
			new_schema = avro_schema_enum(enum_schema->name);
			for (i = 0; i < enum_schema->symbols->num_entries; i++) {
				union {
					st_data_t data;
					char *sym;
				} val;
				st_lookup(enum_schema->symbols, i, &val.data);
				avro_schema_enum_symbol_append(new_schema,
							       val.sym);
			}
		}
		break;

	case AVRO_FIXED:
		{
			struct avro_fixed_schema_t *fixed_schema =
			    avro_schema_to_fixed(schema);
			new_schema =
			    avro_schema_fixed(fixed_schema->name,
					      fixed_schema->size);
		}
		break;

	case AVRO_MAP:
		{
			struct avro_map_schema_t *map_schema =
			    avro_schema_to_map(schema);
			avro_schema_t values_copy =
			    avro_schema_copy(map_schema->values);
			if (!values_copy) {
				return NULL;
			}
			new_schema = avro_schema_map(values_copy);
		}
		break;

	case AVRO_ARRAY:
		{
			struct avro_array_schema_t *array_schema =
			    avro_schema_to_array(schema);
			avro_schema_t items_copy =
			    avro_schema_copy(array_schema->items);
			if (!items_copy) {
				return NULL;
			}
			new_schema = avro_schema_array(items_copy);
		}
		break;

	case AVRO_UNION:
		{
			struct avro_union_schema_t *union_schema =
			    avro_schema_to_union(schema);

			new_schema = avro_schema_union();
			for (i = 0; i < union_schema->branches->num_entries;
			     i++) {
				avro_schema_t schema_copy;
				union {
					st_data_t data;
					avro_schema_t schema;
				} val;
				st_lookup(union_schema->branches, i, &val.data);
				schema_copy = avro_schema_copy(val.schema);
				if (avro_schema_union_append
				    (new_schema, schema_copy)) {
					avro_schema_decref(new_schema);
					return NULL;
				}
			}
		}
		break;

	case AVRO_LINK:
		{
			struct avro_link_schema_t *link_schema =
			    avro_schema_to_link(schema);
			/*
			 * TODO: use an avro_schema_copy of to instead of pointing to
			 * the same reference 
			 */
			avro_schema_incref(link_schema->to);
			new_schema = avro_schema_link(link_schema->to);
		}
		break;

	default:
		return NULL;
	}
	return new_schema;
}

const char *avro_schema_name(const avro_schema_t schema)
{
	if (is_avro_record(schema)) {
		return (avro_schema_to_record(schema))->name;
	} else if (is_avro_enum(schema)) {
		return (avro_schema_to_enum(schema))->name;
	} else if (is_avro_fixed(schema)) {
		return (avro_schema_to_fixed(schema))->name;
	}
	return NULL;
}

/* simple helper for writing strings */
static int avro_write_str(avro_writer_t out, const char *str)
{
	return avro_write(out, (char *)str, strlen(str));
}

static int write_field(avro_writer_t out, struct avro_record_field_t *field)
{
	int rval;
	check(rval, avro_write_str(out, "{\"name\":\""));
	check(rval, avro_write_str(out, field->name));
	check(rval, avro_write_str(out, "\",\"type\":"));
	check(rval, avro_schema_to_json(field->type, out));
	return avro_write_str(out, "}");
}

static int write_record(avro_writer_t out, struct avro_record_schema_t *record)
{
	int rval;
	long i;

	check(rval, avro_write_str(out, "{\"type\":\"record\",\"name\":\""));
	check(rval, avro_write_str(out, record->name));
	check(rval, avro_write_str(out, "\","));
	if (record->space) {
		check(rval, avro_write_str(out, "\"namespace\":\""));
		check(rval, avro_write_str(out, record->space));
		check(rval, avro_write_str(out, "\","));
	}
	check(rval, avro_write_str(out, "\"fields\":["));
	for (i = 0; i < record->fields->num_entries; i++) {
		union {
			st_data_t data;
			struct avro_record_field_t *field;
		} val;
		st_lookup(record->fields, i, &val.data);
		if (i) {
			check(rval, avro_write_str(out, ","));
		}
		check(rval, write_field(out, val.field));
	}
	return avro_write_str(out, "]}");
}
Exemplo n.º 19
0
int main(int argc, char *argv[]) {
    int argchar;
	char* progname = argv[0];
	char** inputfiles = NULL;
	int ninputfiles = 0;
	int i;
	int firstfield=0, lastfield=INT_MAX-1;
	int firstfieldfile=1, lastfieldfile=INT_MAX-1;
	matchfile** mfs;
	MatchObj** mos;
	anbool* eofs;
	anbool* eofieldfile;
	int nread = 0;
	int f;
	int fieldfile;
	int totalsolved, totalunsolved;
	int mode = MODE_BEST;
	double logodds_tosolve = -HUGE_VAL;
	anbool agree = FALSE;

	MatchObj* bestmo;
	bl* keepers;
	bl* leftovers = NULL;

    while ((argchar = getopt (argc, argv, OPTIONS)) != -1) {
		switch (argchar) {
		case 'S':
			solvedfile = optarg;
			break;
		case 's':
			solvedserver = optarg;
			break;
		case 'F':
			mode = MODE_FIRST;
			break;
		case 'a':
			mode = MODE_ALL;
			break;
		case 'r':
			ratio_tosolve = atof(optarg);
			logodds_tosolve = log(ratio_tosolve);
			break;
		case 'f':
			ninfield_tosolve = atoi(optarg);
			break;
		case 'M':
			agreefname = optarg;
			break;
		case 'L':
			leftoverfname = optarg;
			break;
		case 'I':
			firstfieldfile = atoi(optarg);
			break;
		case 'J':
			lastfieldfile = atoi(optarg);
			break;
		case 'A':
			firstfield = atoi(optarg);
			break;
		case 'B':
			lastfield = atoi(optarg);
			break;
		case 'h':
		default:
			printHelp(progname);
			exit(-1);
		}
	}
	if (optind < argc) {
		ninputfiles = argc - optind;
		inputfiles = argv + optind;
	} else {
		printHelp(progname);
		exit(-1);
	}

	if (lastfield < firstfield) {
		fprintf(stderr, "Last field (-B) must be at least as big as first field (-A)\n");
		exit(-1);
	}

	if (solvedserver)
		if (solvedclient_set_server(solvedserver)) {
			fprintf(stderr, "Failed to set solved server.\n");
			exit(-1);
		}

	if (leftoverfname) {
		leftovermf = matchfile_open_for_writing(leftoverfname);
		if (!leftovermf) {
			fprintf(stderr, "Failed to open file %s to write leftover matches.\n", leftoverfname);
			exit(-1);
		}
		BOILERPLATE_ADD_FITS_HEADERS(leftovermf->header);
		qfits_header_add(leftovermf->header, "HISTORY", "This file was created by the program \"agreeable\".", NULL, NULL);
		if (matchfile_write_headers(leftovermf)) {
			fprintf(stderr, "Failed to write leftovers matchfile header.\n");
			exit(-1);
		}
		leftovers = bl_new(256, sizeof(MatchObj));
	}
	if (agreefname) {
		agreemf = matchfile_open_for_writing(agreefname);
		if (!agreemf) {
			fprintf(stderr, "Failed to open file %s to write agreeing matches.\n", agreefname);
			exit(-1);
		}
		BOILERPLATE_ADD_FITS_HEADERS(agreemf->header);
		qfits_header_add(agreemf->header, "HISTORY", "This file was created by the program \"agreeable\".", NULL, NULL);
		if (matchfile_write_headers(agreemf)) {
			fprintf(stderr, "Failed to write agreeing matchfile header.\n");
			exit(-1);
		}
		agree = TRUE;
	}

	solved = il_new(256);
	unsolved = il_new(256);

	keepers = bl_new(256, sizeof(MatchObj));

	totalsolved = totalunsolved = 0;

	mos =  calloc(ninputfiles, sizeof(MatchObj*));
	eofs = calloc(ninputfiles, sizeof(anbool));
	eofieldfile = malloc(ninputfiles * sizeof(anbool));
	mfs = malloc(ninputfiles * sizeof(matchfile*));

	for (i=0; i<ninputfiles; i++) {
		fprintf(stderr, "Opening file %s...\n", inputfiles[i]);
		mfs[i] = matchfile_open(inputfiles[i]);
		if (!mfs[i]) {
			fprintf(stderr, "Failed to open matchfile %s.\n", inputfiles[i]);
			exit(-1);
		}
	}

	// we assume the matchfiles are sorted by field id and number.
	for (fieldfile=firstfieldfile; fieldfile<=lastfieldfile; fieldfile++) {
		anbool alldone = TRUE;

		memset(eofieldfile, 0, ninputfiles * sizeof(anbool));

		for (f=firstfield; f<=lastfield; f++) {
			int fieldnum = f;
			anbool donefieldfile;
			anbool solved_it;
			bl* writematches = NULL;

			// quit if we've reached the end of all the input files.
			alldone = TRUE;
			for (i=0; i<ninputfiles; i++)
				if (!eofs[i]) {
					alldone = FALSE;
					break;
				}
			if (alldone)
				break;

			// move on to the next fieldfile if all the input files have been
			// exhausted.
			donefieldfile = TRUE;
			for (i=0; i<ninputfiles; i++)
				if (!eofieldfile[i] && !eofs[i]) {
					donefieldfile = FALSE;
					break;
				}
			if (donefieldfile)
				break;

			// start a new field.
			fprintf(stderr, "File %i, Field %i.\n", fieldfile, f);
			solved_it = FALSE;
			bestmo = NULL;

			for (i=0; i<ninputfiles; i++) {
				int nr = 0;
				int ns = 0;

				while (1) {
					if (eofs[i])
						break;
					if (!mos[i])
						mos[i] = matchfile_read_match(mfs[i]);
					if (unlikely(!mos[i])) {
						eofs[i] = TRUE;
						break;
					}

					// skip past entries that are out of range...
					if ((mos[i]->fieldfile < firstfieldfile) ||
						(mos[i]->fieldfile > lastfieldfile) ||
						(mos[i]->fieldnum < firstfield) ||
						(mos[i]->fieldnum > lastfield)) {
						mos[i] = NULL;
						ns++;
						continue;
					}

					if (mos[i]->fieldfile > fieldfile)
						eofieldfile[i] = TRUE;

					if (mos[i]->fieldfile != fieldfile)
						break;

					assert(mos[i]->fieldnum >= fieldnum);
					if (mos[i]->fieldnum != fieldnum)
						break;
					nread++;
					if (nread % 10000 == 9999) {
						fprintf(stderr, ".");
						fflush(stderr);
					}

					// if we've already found a solution, skip past the
					// remaining matches in this file...
					if (solved_it && (mode == MODE_FIRST)) {
						ns++;
						mos[i] = NULL;
						continue;
					}

					nr++;

					if ((mos[i]->logodds >= logodds_tosolve)  &&
						(mos[i]->nindex >= ninfield_tosolve)) {
						solved_it = TRUE;
						// (note, we get a pointer to its position in the list)
						mos[i] = bl_append(keepers, mos[i]);
						if (!bestmo || mos[i]->logodds > bestmo->logodds)
							bestmo = mos[i];
					} else if (leftovers) {
						bl_append(leftovers, mos[i]);
					}

					mos[i] = NULL;

				}
				if (nr || ns)
					fprintf(stderr, "File %s: read %i matches, skipped %i matches.\n", inputfiles[i], nr, ns);
			}

			// which matches do we want to write out?
			if (agree) {
				writematches = bl_new(256, sizeof(MatchObj));

				switch (mode) {
				case MODE_BEST:
				case MODE_FIRST:
					if (bestmo)
						bl_append(writematches, bestmo);
					break;
				case MODE_ALL:
					bl_append_list(writematches, keepers);
					break;
				}
			}

			write_field(writematches, leftovers, fieldfile, fieldnum);

			if (agree)
				bl_free(writematches);

			if (leftovers)
				bl_remove_all(leftovers);
			if (keepers)
				bl_remove_all(keepers);

			fprintf(stderr, "This file: %i fields solved, %i unsolved.\n", il_size(solved), il_size(unsolved));
			fprintf(stderr, "Grand total: %i solved, %i unsolved.\n", totalsolved + il_size(solved), totalunsolved + il_size(unsolved));
		}
		totalsolved += il_size(solved);
		totalunsolved += il_size(unsolved);
		
		il_remove_all(solved);
		il_remove_all(unsolved);

		if (alldone)
			break;
	}

	for (i=0; i<ninputfiles; i++)
		matchfile_close(mfs[i]);
	free(mfs);
	free(mos);
	free(eofs);

	fprintf(stderr, "\nRead %i matches.\n", nread);
	fflush(stderr);

	if (keepers)
		bl_free(keepers);
	if (leftovers)
		bl_free(leftovers);

	il_free(solved);
	il_free(unsolved);

	if (leftovermf) {
		matchfile_fix_headers(leftovermf);
		matchfile_close(leftovermf);
	}

	if (agreemf) {
		matchfile_fix_headers(agreemf);
		matchfile_close(agreemf);
	}

	return 0;
}
Exemplo n.º 20
0
void output_dump( const struct Field fldi,
				  const double t) {	
				  
	FILE *ht;
	int dump_version,i;
	int size_x,	size_y, size_z;
	int marker, included_field;
	int nfield;
	long int filesize;
	
	ht=NULL;
	
	DEBUG_START_FUNC;
	
	size_x = NX;
	size_y = NY;
	size_z = NZ;
	
	// This is a check when we try to read a dump file
	dump_version = OUTPUT_DUMP_VERSION;
	
	// This is a hard coded marker to check that we have correctly read the file
	marker = DUMP_MARKER;
	
	if(rank==0) {
		ht=fopen(OUTPUT_DUMP_WRITE,"w");
		if(ht==NULL) ERROR_HANDLER( ERROR_CRITICAL, "Error opening dump file.");
	
		fwrite(&dump_version, sizeof(int), 1, ht);
	
		fwrite(&size_x		, sizeof(int), 1, ht);
		fwrite(&size_y		, sizeof(int), 1, ht);
		fwrite(&size_z		, sizeof(int), 1, ht);
		// Included fields
		// First bit is Boussinesq fields
		// Second bit is MHD fields
		// Other fields can be added from that stage...
		included_field=0;
#ifdef BOUSSINESQ
		included_field+=1;
#endif
#ifdef MHD
		included_field+=2;
#endif
		fwrite(&included_field, sizeof(int), 1, ht);
	}
	
	write_field(ht, fldi.vx);
	write_field(ht, fldi.vy);
	write_field(ht, fldi.vz);
	
#ifdef BOUSSINESQ
	write_field(ht, fldi.th);
#endif
#ifdef MHD
	write_field(ht, fldi.bx);
	write_field(ht, fldi.by);
	write_field(ht, fldi.bz);
#endif

	if(rank==0) {
		fwrite(&t			, sizeof(double)		   , 1			   , ht);
	
		fwrite(&noutput_flow		, sizeof(int)			   , 1             , ht);
		fwrite(&lastoutput_time 	, sizeof(double)		   , 1			   , ht);
		fwrite(&lastoutput_flow 	, sizeof(double)		   , 1			   , ht);
		fwrite(&lastoutput_dump 	, sizeof(double)		   , 1			   , ht);
	
// Any extra information should be put here.

		if(param.numericalkevol){//AJB 09/03/12
		   for(i=0;i<9;i++){  fwrite(&kbasis[i],sizeof(double),1,ht); }
		}
	
		fwrite(&marker		, sizeof(int)			   , 1			   , ht);
	
// Check everything was fine with the file
		
		if(ferror(ht)) ERROR_HANDLER( ERROR_CRITICAL, "Error writing dump file");
		
		fclose(ht);
	}
	
	// predict the file size:
	nfield = 3;		// Velocity fields
#ifdef BOUSSINESQ
	nfield += 1;
#endif
#ifdef MHD
	nfield += 3;
#endif

	filesize = nfield * sizeof(double complex) * NTOTAL_COMPLEX * NPROC + 4 * sizeof( double) + 7 * sizeof( int );
	if(param.numericalkevol) {//AJB 09/03/12
	  filesize = nfield * sizeof(double complex) * NTOTAL_COMPLEX * NPROC + 13 * sizeof( double) + 7 * sizeof( int );
	}
	
	if( check_file_size( OUTPUT_DUMP_WRITE, filesize ) ) {
		MPI_Printf("Error checking the dump size, got %d instead of %d\n", (int) check_file_size( OUTPUT_DUMP_WRITE, filesize), (int) filesize);
		ERROR_HANDLER( ERROR_CRITICAL, "Error writing dump file, check your quotas");
	}
	
// This bit prevents the code from losing all the dump files (this kind of thing happens sometimes...)
// With this routine, one will always have a valid restart dump, either in OUTPUT_DUMP_WRITE, OUTPUT_DUMP or OUTPUT_DUMP_SAV 
// (it should normally be in OUTPUT_DUMP)

	if(rank==0) {
		remove(OUTPUT_DUMP_SAV);				 // Delete the previously saved output dump
		rename(OUTPUT_DUMP, OUTPUT_DUMP_SAV);	 // Save the current dump file
		rename(OUTPUT_DUMP_WRITE, OUTPUT_DUMP);  // Move the new dump file to its final location
	}
	
	if( check_file_size( OUTPUT_DUMP, filesize ) ) {
		MPI_Printf("Error checking the dump size, got %d instead of %d\n", (int) check_file_size( OUTPUT_DUMP, filesize), (int) filesize);
		ERROR_HANDLER( ERROR_CRITICAL, "Error writing dump file, check your quotas");
	}
	
#ifdef MPI_SUPPORT
	MPI_Barrier(MPI_COMM_WORLD);
#endif
	DEBUG_END_FUNC;
	
	return;
}
Exemplo n.º 21
0
int main(void)
    {
    double inmon, tmon;
    double mon, nxt, lst;
    double *iyr;
    double *nyr;
    double dyr, day;
    double ndyr;
    double *dy;
    double dmon[12];
    double dbmon;
    double yearday;
    int imon, inxt, ilst;
# ifndef WRTTS
    int itts; /* tracer time step counter */
# endif
    int nmnfirst;
#ifdef SEPFILES
    double smon, snxt;
    int ismon, isnxt, ihnxt;
#endif

#ifndef WRTTS
    size_t nrec = 0;
#endif
    int err, i, j, k;
    int cmon;
    int nmn;
    double frac;
    static int m;
#ifndef WRTTS
    int varmap[NOVARS];

    FILE *fn;
    char output_filename[200];
#endif
    char run_name[200];
    char restart_filename[200];
    struct vardesc var_out[NOVARS];
#ifndef WRTTS
    struct varcdfinfo varinfo[NOVARS];
    int nvar = 0, cdfid, timeid[2];
#endif

    extern int flags[NOVARS];
    extern int rflags[NOVARS];

    //BX-a  for testing only
    int status;
    char message[144];
    //BX-e

    //BX  allocate tracer fields
    err = alloc_arrays();
    if (err)
	printf("Error allocating arrays.\n");

    err = alloc_trac();
    if (err)
	printf("Error allocating tracer field.\n");

    iyr = malloc(sizeof(double));
    nyr = malloc(sizeof(double));
    dy = malloc(sizeof(double));

    mlen[0] = 31; /* January      */
    mlen[1] = 28; /* February     */
    mlen[2] = 31; /* March        */
    mlen[3] = 30; /* April        */
    mlen[4] = 31; /* May          */
    mlen[5] = 30; /* June         */
    mlen[6] = 31; /* July         */
    mlen[7] = 31; /* August       */
    mlen[8] = 30; /* September    */
    mlen[9] = 31; /* October      */
    mlen[10] = 30; /* November     */
    mlen[11] = 31; /* December     */

    dmon[0] = 0.0;

    for (i = 1; i <= 11; i++)
	{
	dmon[i] = dmon[i - 1] + mlen[i - 1];
	}

    /*----------------------------------*
     *
     *     get user input
     *
     *----------------------------------*/

    {
    char line[100];
    int scan_count, done = 1;

    printf("Enter directory to use to read.\n");
    fgets(directory, sizeof(directory), stdin);

    directory[strlen(directory) - 1] = '\0';
    k = strlen(directory);
    if (k > 0)
	if (directory[k - 1] != '/')
	    {
	    directory[k] = '/';
	    directory[k + 1] = '\0';
	    printf("Using directory %s first.\n", directory);
	    }

    strcat(directory, fname);
    strcpy(fname, directory);
    printf("file path = %s\n", fname);

    while (done)
	{

	printf(
		"\nEnter the starting month and the total months to integrate.\n");

	fgets(line, sizeof(line), stdin);
	line[strlen(line) - 1] = '\0';
	scan_count = sscanf(line, "%lg, %lg,", &inmon, &tmon);
	if (scan_count == 2)
	    {
	    if (inmon < 0 || tmon < 0)
		printf("Negative values not allowed\n");
	    else
		done = 0;
	    }
	else
	    printf("Incorrect number of values, %d, read.\n", scan_count);
	}

    printf("\ninitial month = %g \n", inmon);
    printf("final month = %g \n", inmon + tmon - 1);
    printf("total months = %g \n\n", tmon);

    /*-----------------------------------
     *
     *     set output print flags to 0
     *
     *     added restart flags as a restart bug fix until
     *     memory restriction problem is solved 31OCT07 BX
     *
     *----------------------------------*/

    for (i = 0; i <= NOVARS - 1; i++)
	flags[i] = 0;
    for (i = 0; i <= NOVARS - 1; i++)
	rflags[i] = 0;

    flags[1] = 0;
    flags[2] = 0; /* u,v */
    rflags[1] = 0;
    rflags[2] = 0; /* u,v */
    flags[0] = 0;
    flags[3] = 0; /* D, h */
    rflags[0] = 0;
    rflags[3] = 0; /* D, h */
    flags[4] = 0;
    flags[5] = 0; /* uhtm, vhtm */
    rflags[4] = 0;
    rflags[5] = 0; /* uhtm, vhtm */
    flags[6] = 0;
    flags[7] = 0;
    flags[8] = 0; /* ea, eb, eaml */
    flags[18] = 0; /* ML potential density */
    rflags[18] = 0; /* ML potential density */
#ifdef AGE
    flags[9] = 1;
    rflags[9] = 1; /* ideal age tracer*/
#endif

    printf("Enter base name for output\n");

    fgets(run_name, sizeof(run_name), stdin);
    run_name[strlen(run_name) - 1] = '\0';
    sprintf(output_filename, "%s.%04g.nc", run_name, inmon + tmon - 1);
    printf("Create NetCDF output file '%s'.\n", output_filename);



    } // end of block "get user input"

    //DT
    lastsave = -1;
    //DT

    /*-----------------------------------
     *
     *     allocate and initialize fields
     *
     *----------------------------------*/

    read_grid();
    printf("Done reading grid or metric file.\n");

    set_metrics();
    printf("Done setting metrics.\n");

    /* Copy the variable descriptions to a list of the actual output variables. */
    for (i = 0; i < NOVARS; i++)
	if (flags[i] > 0)
	    {
	    var_out[nvar] = vars[i];
	    varmap[i] = nvar;
	    nvar++;
	    }
    // force float precision output with last argument
    printf("Making NETCDF %s file\n", output_filename);
    create_file(output_filename, NETCDF_FILE, var_out, nvar, &fn, &cdfid,
	    timeid, varinfo, 1);
    // don't force
    // create_file(output_filename, NETCDF_FILE, var_out, nvar, &fn, &cdfid, timeid, varinfo, 0);
    printf("Closing file \n");
    close_file(&cdfid, &fn);

    /* Allocate the memory for the fields to be calculated.		*/
    alloc_fields();

    /* initialize tracer pointers					*/

    for (m = 0; m < NOVARS; m++)
	{
	if (flags[m])
	    for (k = 0; k < varsize[m]; k++)
		var[m][k] = 0.0;
	}

    /********** set means to zero                                   */
    /*  2d variables */
    if (flags[8])
	set_fix_darray2d_zero(mn_eaml);


    /*  3d variables */
    if (flags[1])
	set_darray3d_zero(mn_u, NZ, NXMEM, NYMEM);
    if (flags[2])
	set_darray3d_zero(mn_v, NZ, NXMEM, NYMEM);
    if (flags[3])
	set_darray3d_zero(mn_h, NZ, NXMEM, NYMEM);
    if (flags[4])
	set_darray3d_zero(mn_uhtm, NZ, NXMEM, NYMEM);
    if (flags[5])
	set_darray3d_zero(mn_vhtm, NZ, NXMEM, NYMEM);
    if (flags[6])
	set_darray3d_zero(mn_ea, NZ, NXMEM, NYMEM);
    if (flags[7])
	set_darray3d_zero(mn_eb, NZ, NXMEM, NYMEM);
#ifdef AGE
    if (flags[9])
	set_darray3d_zero(mn_age, NZ, NXMEM, NYMEM);

#endif
    printf("Reading bathymetry, D.\n");

    // initialize D to be all ocean first

    for (i = 0; i <= NXMEM - 1; i++)
	{
	for (j = 0; j <= NYMEM - 1; j++)
	    {
	    D[i][j] = MINIMUM_DEPTH;
	    }
	}
#ifndef USE_CALC_H
    printf("calling read_D\n");
    read_D();

    for (i = 0; i <= NXMEM - 1; i++)
	for (j = 0; j <= NYMEM - 1; j++)
	    if (D[i][j] < 10.0)
		D[i][j] = MINIMUM_DEPTH;
#endif

    read_grid();
    set_metrics();

    dyr = inmon / 12;
    smon = (double) ((int) inmon % NMONTHS);
    mon = 12 * modf(dyr, iyr);

    printf("\n initial mon = %g - %g - %g \n\n", inmon, smon, mon);


    imon = (int) (mon + 0.00001);
    /* Begin edit DT */
    int iyear = floor((inmon + imon) / 12);
    theyear = iyear;
#ifdef RESTART
    theyear++;
    iyear++;
#endif
    /*  End edit DT  */
    inxt = imon + 1;

    ismon = (int) (smon + 0.00001) % NMONTHS;

    isnxt = (ismon+1) % NMONTHS;
    ihnxt = (ismon+2) % NMONTHS;

    dbmon = (double) inmon;
    lst = 12 * modf((dbmon - 1 + 12) / 12, iyr);
    ilst = (int) (lst + 0.00001);

    // ashao: Read in next month's isopycnal thickness fields
    // (will be copied at the beginning of the integration)
    // Done this way so that if hindcasts are used the physical fields switch smoothly
    // to/from climatological fields
    //BX  files are not in regular order (uvw are midmonth and h starts with last month)

        currtime = BEGYEAR;
    if (usehindcast) {
        // Check to see if simulation started within the hindcast years
        if ( (currtime >= BEGHIND) || (currtime < (ENDHIND+1) ) ) {
        	hindindex=inmon;
        	read_h(ismon,hend,"hind");
        }
    }
    else {
    	read_h(ismon, hend,"clim");
    }
    // for files in regular order (h before uvw) use code here
    //BX
    // read_uvw(imon,1);
    //BX
    // read_h(imon,inxt);



#ifdef USE_CALC_H
    z_sum(h, D);
#endif
    printf("\nSetting up and initializing\n");

#ifdef RESTART
    initialize(inmon,run_name);
#else
    initialize(imon);
#endif
    nmn = 0;

    //HF the next line should be in init.h (and be optional!)
#undef OUTPUT_IC
#ifdef OUTPUT_IC
    /*-----------------------------------
     *
     *     write tracer initial conditions
     *
     *----------------------------------*/

    printf("Writing initial condition variables out to netCDF\n\n",cmon);

    //  open netcdf file for each writing
    status = nc_open(output_filename, NC_WRITE, &cdfid);
    if (status != NC_NOERR)
	{
	strcpy(message,"Opening file"); strcat(message,output_filename);
	handle_error(message,status);
	}

    err = write_time(cdfid,fn,timeid[0],nrec, dy);
    if (err == -1) printf("Error writing day.\n");

    if (flags[3])
	{
	for (k=0;k<NZ;k++)
	    for (i=0;i<NXMEM;i++)
		for (j=0;j<NYMEM;j++)
		    mn_h[k][i][j] += h[k][i][j];
	}

#ifdef AGE
    if (flags[9]) add_darray3d(mn_age, age, NZ, NXMEM, NYMEM);
    /*{
     for (k=0;k<NZ;k++)
     for (i=0;i<NXMEM;i++)
     for (j=0;j<NYMEM;j++)
     mn_age[k][i][j] += age[k][i][j];
     }*/
#endif /* AGE */


    for (m=0;m<NOVARS;m++) if (flags[m])
	{
	err = write_field(cdfid, fn, vars[m], varinfo[varmap[m]],
		nrec,var[m]);
	if (err == -1) printf("Error writing %s.\n",vars[m].name);
	}
    //  close file after each writing
    close_file(&cdfid, &fn);
    printf("netcdf record = %d\n",nrec++);
#endif /* OUTPUT_IC */




    /*-------------------------------------------------------------------*
     *
     *     begin integration loop
     *
     *-------------------------------------------------------------------*/

    mon = 0.0; /* reiniti */
    nmnfirst = 1;


    for (cmon = inmon; cmon < inmon + tmon; cmon++)
	{
	nmn++;

	dyr = cmon / 12.0;
	ndyr = (cmon + 1) / 12.0;

	dbmon = (double) cmon;
	lst = 12 * modf((dbmon - 1 + 12) / 12, iyr);
	ilst = (int) (lst + 0.00001);
	printf("double-mon=%g,lastmon=%g,ilst=%i\n", dbmon, lst, ilst);


	smon = (double) ((int) cmon % NMONTHS);
	snxt = (double) ((int) (cmon + 1) % NMONTHS);

	mon = 12.0 * modf(dyr, iyr);
	nxt = 12.0 * modf(ndyr, nyr);

	printf("the current month is %i-%g-%g \n", cmon, smon, mon);
	printf("the current year is %g \n", *iyr);

	imon = (int) (mon + 0.00001);
	inxt = (int) (nxt + 0.00001);

	ismon = (int) (smon + 0.00001);
	isnxt = (int) (snxt + 0.00001);

	yearday = 0;
	for (i=0;i<=imon;i++) yearday += dmon[imon];
	currtime = *iyr + BEGYEAR + yearday/365.0;

	day = (*iyr) * 365.0 + dmon[imon];
	*dy = currtime;

	printf("the current day is -%g- \n", *dy);
	printf("the current ismon/smon is -%i-%g- \n", ismon, smon);
	printf("the next smonth/mean index: -%i- \n", isnxt);

	dt = ((double) mlen[imon]);
	dt = dt * 86400 / (double) NTSTEP;


	for (itts = 1; itts <= NTSTEP; itts++)
	    {
	    printf("\nSub time step number= %i \n", itts);
	    /*-----------------------------------
	     *
	     *     get physical fields and bc's
	     *
	     *----------------------------------*/

	    printf("Month %d timestamp Start: %4.2f End: %4.2f\n",cmon,currtime,currtime+dt/31536000);
	    currtime += dt / 31536000; //ashao: advance currenttime
	    copy_2fix_darray3d(hstart,hend,NZ,NXMEM,NYMEM);
	    copy_2fix_darray3d(h,hstart,NZ,NXMEM,NYMEM);
	    if (usehindcast) {
	        if ( ( cmon >= starthindindex) && ( hindindex <= (numhindmonths-1) )) {
			
			printf("Reading in UVW from hindcast\n");
	        	read_uvw(hindindex,"hind");
		        read_h(hindindex,hend,"hind");
	        	hindindex++;
	        }
		else {
		
		printf("Reading in UVW from climatology\n");
	    	read_uvw(isnxt,"clim");
	    	read_h(isnxt, hend,"clim");
		}
	    }
	    else {
		printf("Reading in UVW from climatology\n");
	    	read_uvw(isnxt,"clim");
	    	read_h(isnxt, hend,"clim");
	    }
	    printf("Month- hstart:%d hend:%d\n",ismon,isnxt);

	    /*-----------------------------------
	     *
	     *     integrate 1 time step
	     *
	     *----------------------------------*/

	    printf("step fields - day = %g\n\n", day);
	    step_fields(iyear, itts, imon, iterno); // modified ashao


	    /*-------------------------------------------------------------------*
	     *
	     *     end integration loop
	     *
	     *-------------------------------------------------------------------*/

	    /*-----------------------------------
	     *
	     *     calculate tracer averages
	     *
	     *----------------------------------*/

	    printf("calculate tracer averages\n");

	    if (flags[8])
		add_fix_darray2d(mn_eaml, eaml);
	    if (flags[1])
		add_darray3d(mn_u, u, NZ, NXMEM, NYMEM);
	    if (flags[2])
		add_darray3d(mn_v, v, NZ, NXMEM, NYMEM);
	    if (flags[3])
		{
		for (k = 0; k < NZ; k++)
		    for (i = 0; i < NXMEM; i++)
			for (j = 0; j < NYMEM; j++)
			    {
			    mn_h[k][i][j] += h[k][i][j];
			    }
		}
	    if (flags[4])
		add_darray3d(mn_uhtm, uhtm, NZ, NXMEM, NYMEM);
	    if (flags[5])
		add_darray3d(mn_vhtm, vhtm, NZ, NXMEM, NYMEM);
	    if (flags[6])
		add_darray3d(mn_ea, ea, NZ, NXMEM, NYMEM);
	    if (flags[7])
		add_darray3d(mn_eb, eb, NZ, NXMEM, NYMEM);
#ifdef AGE
	    //DT
	    //    if (flags[9]) add_darray3d(mn_age, age, NZ, NXMEM, NYMEM);
	    if (flags[9])
	    {
	    	for (k = 0; k < NZ; k++)
	    	{
	    		for (i = 0; i < NXMEM; i++)
	    		{
	    			for (j = 0; j < NYMEM; j++)
	    			{
	    				if (age[k][i][j] > 0.0)
	    				{
	    					{
	    						mn_age[k][i][j] += age[k][i][j];
	    					}
	    				}}}}}

	    				//DT
#endif
	    if (flags[18])
		{
		for (k = 0; k < 2; k++)
		    for (i = 0; i < NXMEM; i++)
			for (j = 0; j < NYMEM; j++)
			    mn_rml[k][i][j] += rml[k][i][j];
		}


	    /* calculate the mean */

	    if (nmn == WRINT && itts == 1)
		{
		printf("***nmn= %i, itts= %i, nmnfirst= %i\n", nmn, itts,
			nmnfirst);
		frac = 1.0 / ((double) nmn * (double) NTSTEP);

		if (flags[8])
		    mult_fix_darray2d(mn_eaml, frac);
		if (flags[1])
		    mult_darray3d(mn_u, NZ, NXMEM, NYMEM, frac);
		if (flags[2])
		    mult_darray3d(mn_v, NZ, NXMEM, NYMEM, frac);
		if (flags[3])
		    mult_darray3d(mn_h, NZ, NXMEM, NYMEM, frac);
		if (flags[4])
		    mult_darray3d(mn_uhtm, NZ, NXMEM, NYMEM, frac);
		if (flags[5])
		    mult_darray3d(mn_vhtm, NZ, NXMEM, NYMEM, frac);
		if (flags[6])
		    mult_darray3d(mn_ea, NZ, NXMEM, NYMEM, frac);
		if (flags[7])
		    mult_darray3d(mn_eb, NZ, NXMEM, NYMEM, frac);
#ifdef AGE
		if (flags[9])
		    mult_darray3d(mn_age, NZ, NXMEM, NYMEM, frac);
#endif

		if (flags[18])
		    mult_darray3d_mv(mn_rml, 2, NXMEM, NYMEM, frac, D, misval);

		/*-----------------------------------
		 *
		 *     write tracer averages and reset to 0
		 *
		 *----------------------------------*/
		printf("Writing month %i variables out to netCDF\n\n", cmon);

		status = nc_open(output_filename, NC_WRITE, &cdfid);
		if (status != NC_NOERR)
		    {
		    strcpy(message, "Opening file");
		    strcat(message, output_filename);
		    handle_error(message, status);
		    }

		err = write_time(cdfid, fn, timeid[0], nrec, dy);
		if (err == -1)
		    printf("Error writing day.\n");

		for (m = 0; m < NOVARS; m++)
		    if (flags[m]==1)
			{
			printf("m = %d\n",m);
			err = write_field(cdfid, fn, vars[m],
				varinfo[varmap[m]], nrec, var[m]);
			if (err == -1)
			    printf("Error writing %s.\n", vars[m].name);
			}
		close_file(&cdfid, &fn);

		/*    reset all means to zero */
		nmn = 0;
		if (flags[8])
		    set_fix_darray2d_zero(mn_eaml);
		if (flags[1])
		    set_darray3d_zero(mn_u, NZ, NXMEM, NYMEM);
		if (flags[2])
		    set_darray3d_zero(mn_v, NZ, NXMEM, NYMEM);
		if (flags[3])
		    set_darray3d_zero(mn_h, NZ, NXMEM, NYMEM);
		if (flags[4])
		    set_darray3d_zero(mn_uhtm, NZ, NXMEM, NYMEM);
		if (flags[5])
		    set_darray3d_zero(mn_vhtm, NZ, NXMEM, NYMEM);
		if (flags[6])
		    set_darray3d_zero(mn_ea, NZ, NXMEM, NYMEM);
		if (flags[7])
		    set_darray3d_zero(mn_eb, NZ, NXMEM, NYMEM);
		if (flags[18])
		    set_darray3d_zero(mn_rml, 2, NXMEM, NYMEM);
#ifdef AGE
		if (flags[9])
		    set_darray3d_zero(mn_age, NZ, NXMEM, NYMEM);

#endif
		// begin ashao
		// end ashao

		printf("netcdf record = %d\n", nrec + 1);
		nrec++;

		} /*  end if nmn==WRITEINT */

	    /*-------------------------------------------------------------------*
	     *
	     *     end integration loop
	     *
	     *-------------------------------------------------------------------*/

	    } /* end itts loop over NTSTEP */
	} /* end while */

    //BX-a
    /*-----------------------------------
     *
     *     write restart file
     *
     *----------------------------------*/

    //   First write the up-to-date tracer values to the mean fields.
    //   In order to save memory the instantaneous values for the
    //   restart will be written on mean fields in the restart file.

    printf("start of array copying\n");
    //HF #ifdef SMOOTH_REST
    copy_fix_darray3d(mn_h, h, NZ, NXMEM, NYMEM);
    //HF #endif
#ifdef AGE
    copy_darray3d(mn_age, age, NZ, NXMEM, NYMEM);
#endif
    for (k = 0; k < NZ; k++)
	{
	for (i = 0; i < NXMEM; i++)
	    {
	    for (j = 0; j < NYMEM; j++)
		{
		} /* for j loop */
	    } /* for i loop */
	} /* for k loop */

    //  Second, create restart file name and open file

    sprintf(restart_filename, "restart.%s.%04d.nc", run_name, cmon);
    printf("Writing NetCDF restart file '%s'.\n\n", restart_filename);

    /* Copy the variable descriptions to a list of the actual restart variables. */
    nvar = 0;
    for (i = 0; i < NOVARS; i++)
	if (rflags[i] > 0)
	    {
	    var_out[nvar] = vars[i];
	    varmap[i] = nvar;
	    nvar++;
	    }

    // do NOT force float precision output with last argument
    create_file(restart_filename, NETCDF_FILE, var_out, nvar, &fn, &cdfid,
	    timeid, varinfo, 0);

    for (m = 0; m < NOVARS; m++)
	if (rflags[m])
	    {
	    err = write_field(cdfid, &fn, vars[m], varinfo[varmap[m]], 0,
		    var[m]);
	    if (err == -1)
		printf("Error writing %s.\n", vars[m].name);
	    }

    close_file(&cdfid, &fn);

    printf("\n programme termine normallement. \n");
    return (0);
    }
Exemplo n.º 22
0
void write_ts(double wrts)
    {
    int i,j,k,m;
    int status;
    char message[144];
    int err;
    double *wrdy;
#ifdef WRTTS
    wrdy = malloc(sizeof(double));
#endif
    /********** set means to zero                                   */
    /*  2d variables */
    if (flags[8]) set_fix_darray2d_zero(mn_eaml);
    /*---------------------------------------
     *
     *     write tracer values on output field
     *
     *--------------------------------------*/

    printf("write output field\n");

    if (flags[8]) add_fix_darray2d(mn_eaml, eaml);
    //HF outer if, inner for loops, instead of vice versa!
    //HF think about writing appropriate subroutine(s)!!!
    if (flags[1]) copy_darray3d(mn_u, u, NZ, NXMEM, NYMEM);
    /*{
     for (k=0;k<NZ;k++)
     for (i=0;i<NXMEM;i++)
     for (j=0;j<NYMEM;j++)
     mn_u[k][i][j] = u[k][i][j];
     } */
    if (flags[2]) copy_darray3d(mn_v, v, NZ, NXMEM, NYMEM);
    /* {
     for (k=0;k<NZ;k++)
     for (i=0;i<NXMEM;i++)
     for (j=0;j<NYMEM;j++)
     mn_v[k][i][j] = v[k][i][j];
     }*/
    if (flags[3])
	{
	for (k=0;k<NZ;k++)
	    for (i=0;i<NXMEM;i++)
		for (j=0;j<NYMEM;j++)
		    mn_h[k][i][j] = h[k][i][j];
	}
    if (flags[4]) copy_darray3d(mn_uhtm, uhtm, NZ, NXMEM, NYMEM);
    /*{
     for (k=0;k<NZ;k++)
     for (i=0;i<NXMEM;i++)
     for (j=0;j<NYMEM;j++)
     mn_uhtm[k][i][j] = uhtm[k][i][j];
     }*/
    if (flags[5]) copy_darray3d(mn_vhtm, vhtm, NZ, NXMEM, NYMEM);
    /*{
     for (k=0;k<NZ;k++)
     for (i=0;i<NXMEM;i++)
     for (j=0;j<NYMEM;j++)
     mn_vhtm[k][i][j] = vhtm[k][i][j];
     }*/
    if (flags[6])
	{
	for (k=0;k<NZ;k++)
	    for (i=0;i<NXMEM;i++)
		for (j=0;j<NYMEM;j++)
		    mn_ea[k][i][j] = ea[k][i][j];
	}
    if (flags[7])
	{
	for (k=0;k<NZ;k++)
	    for (i=0;i<NXMEM;i++)
		for (j=0;j<NYMEM;j++)
		    mn_eb[k][i][j] = Salttm[k][i][j];
	}
#ifdef AGE
    if (flags[9]) copy_darray3d(mn_age, age, NZ, NXMEM, NYMEM);
#endif
    if (flags[18])
	{
	for (k=0;k<2;k++)
	    for (i=0;i<NXMEM;i++)
		for (j=0;j<NYMEM;j++)
		    mn_rml[k][i][j] = rml[k][i][j];
	}
	    printf("Writing variables for sub timestep %i out to netCDF\n\n",itts);
	    //  open netcdf file for each writing
	    status = nc_open(output_filename, NC_WRITE, &cdfid);
	    if (status != NC_NOERR)
		{
		strcpy(message,"Opening file"); strcat(message,output_filename);
		handle_error(message,status);
		}
	    *wrdy = wrts;
	    err = write_time(cdfid,fn,timeid[0],nrec, wrdy);
	    if (err == -1) printf("Error writing day.\n");

	    for (m=0;m<NOVARS;m++) if (flags[m])
		{
		err = write_field(cdfid, fn, vars[m], varinfo[varmap[m]],
			nrec,var[m]);
		if (err == -1) printf("Error writing %s.\n",vars[m].name);
		}
	    close_file(&cdfid, &fn);

	    printf("netcdf record = %d\n",nrec++);
	    }
Exemplo n.º 23
0
Arquivo: mc.c Projeto: mpmccode/mpmc
/* implements the Markov chain */
int mc(system_t *system) {
    int j, msgsize;
    double initial_energy, final_energy, current_energy;
    double rot_partfunc;
    observables_t *observables_mpi;
    avg_nodestats_t *avg_nodestats_mpi;
    sorbateInfo_t *sinfo_mpi = 0;
    double *temperature_mpi = 0;
    char *snd_strct = 0, *rcv_strct = 0;
    system->count_autorejects = 0;  // initialize counter for skipped close (unphysical) contacts
                                    // char linebuf[MAXLINE];  (unused variable)
#ifdef MPI
    MPI_Datatype msgtype;
#endif /* MPI */

    /* allocate the statistics structures */
    observables_mpi = calloc(1, sizeof(observables_t));
    memnullcheck(observables_mpi, sizeof(observables_t), __LINE__ - 1, __FILE__);
    avg_nodestats_mpi = calloc(1, sizeof(avg_nodestats_t));
    memnullcheck(avg_nodestats_mpi, sizeof(avg_nodestats_t), __LINE__ - 1, __FILE__);
    // if multiple-sorbates, allocate sorb statistics struct
    if (system->sorbateCount > 1) {
        sinfo_mpi = calloc(system->sorbateCount, sizeof(sorbateInfo_t));
        memnullcheck(sinfo_mpi, sizeof(sorbateInfo_t), __LINE__ - 1, __FILE__);
        system->sorbateGlobal = calloc(system->sorbateCount, sizeof(sorbateAverages_t));
        memnullcheck(system->sorbateGlobal, sizeof(sorbateAverages_t), __LINE__ - 1, __FILE__);
    }

    // compute message size
    msgsize = sizeof(observables_t) + sizeof(avg_nodestats_t);
    if (system->calc_hist) msgsize += system->n_histogram_bins * sizeof(int);
    if (system->sorbateCount > 1) msgsize += system->sorbateCount * sizeof(sorbateInfo_t);

#ifdef MPI
    MPI_Type_contiguous(msgsize, MPI_BYTE, &msgtype);
    MPI_Type_commit(&msgtype);
#endif /* MPI */

    /* allocate MPI structures */
    snd_strct = calloc(msgsize, 1);
    memnullcheck(snd_strct, sizeof(msgsize), __LINE__ - 1, __FILE__);
    if (!rank) {
        rcv_strct = calloc(size, msgsize);
        memnullcheck(rcv_strct, size * sizeof(msgsize), __LINE__ - 1, __FILE__);
        temperature_mpi = calloc(size, sizeof(double));  //temperature list for parallel tempering
        memnullcheck(temperature_mpi, size * sizeof(double), __LINE__ - 1, __FILE__);
    }

    /* update the grid for the first time */
    if (system->cavity_bias) cavity_update_grid(system);

    /* set volume observable */
    system->observables->volume = system->pbc->volume;

    /* get the initial energy of the system */
    initial_energy = energy(system);

#ifdef QM_ROTATION
    /* solve for the rotational energy levels */
    if (system->quantum_rotation) quantum_system_rotational_energies(system);
#endif /* QM_ROTATION */

    /* be a bit forgiving of the initial state */
    if (!isfinite(initial_energy))
        initial_energy = system->observables->energy = MAXVALUE;

    /* if root, open necessary output files */
    if (!rank)
        if (open_files(system) < 0) {
            error(
                "MC: could not open files\n");
            return (-1);
        }

    // write initial observables to stdout and logs
    if (!rank) {
        calc_system_mass(system);
        // average in the initial values once  (we don't want to double-count the initial state when using MPI)
        update_root_averages(system, system->observables, system->avg_observables);
        // average in the initial sorbate values
        if (system->sorbateCount > 1) {
            update_sorbate_info(system);                             //local update
            update_root_sorb_averages(system, system->sorbateInfo);  //global update
        }
        // write initial observables exactly once
        if (system->file_pointers.fp_energy)
            write_observables(system->file_pointers.fp_energy, system, system->observables, system->temperature);
        if (system->file_pointers.fp_energy_csv)
            write_observables_csv(system->file_pointers.fp_energy_csv, system, system->observables, system->temperature);
        output(
            "MC: initial values:\n");
        write_averages(system);
    }

    /* save the initial state */
    checkpoint(system);

    /* main MC loop */
    for (system->step = 1; system->step <= system->numsteps; (system->step)++) {
        /* restore the last accepted energy */
        initial_energy = system->observables->energy;

        /* perturb the system */
        make_move(system);

        /* calculate the energy change */
        final_energy = energy(system);

#ifdef QM_ROTATION
        /* solve for the rotational energy levels */
        if (system->quantum_rotation && (system->checkpoint->movetype == MOVETYPE_SPINFLIP))
            quantum_system_rotational_energies(system);
#endif /* QM_ROTATION */
        if (system->checkpoint->movetype != MOVETYPE_REMOVE)
            rot_partfunc = system->checkpoint->molecule_altered->rot_partfunc;
        else
            rot_partfunc = system->checkpoint->molecule_backup->rot_partfunc;

        /* treat a bad contact as a reject */
    if (!isfinite(final_energy)){
            system->observables->energy = MAXVALUE;
            system->nodestats->boltzmann_factor = 0;
        } else
            boltzmann_factor(system, initial_energy, final_energy, rot_partfunc);

        /* Metropolis function */
        if ((get_rand(system) < system->nodestats->boltzmann_factor) && (system->iter_success == 0)) {
            /////////// ACCEPT

            current_energy = final_energy;

            /* checkpoint */
            checkpoint(system);
            register_accept(system);

            /* SA */
            if (system->simulated_annealing) {
                if (system->simulated_annealing_linear == 1) {
                    system->temperature = system->temperature + (system->simulated_annealing_target - system->temperature) / (system->numsteps - system->step);
                    if (system->numsteps - system->step == 0)
                        system->temperature = system->simulated_annealing_target;
                } else
                    system->temperature = system->simulated_annealing_target + (system->temperature - system->simulated_annealing_target) * system->simulated_annealing_schedule;
            }

        } else {
            /////////////// REJECT

            current_energy = initial_energy;  //used in parallel tempering

            //reset the polar iterative failure flag
            system->iter_success = 0;

            /* restore from last checkpoint */
            restore(system);
            register_reject(system);

        }  // END REJECT

        // perform parallel_tempering
        if ((system->parallel_tempering) && (system->step % system->ptemp_freq == 0))
            temper_system(system, current_energy);

        /* track the acceptance_rate */
        track_ar(system->nodestats);

        /* each node calculates its stats */
        update_nodestats(system->nodestats, system->avg_nodestats);

        /* do this every correlation time, and at the very end */
        if (!(system->step % system->corrtime) || (system->step == system->numsteps)) {
            /* copy observables and avgs to the mpi send buffer */
            /* histogram array is at the end of the message */
            if (system->calc_hist) {
                zero_grid(system->grids->histogram->grid, system);
                population_histogram(system);
            }

            // update frozen and total system mass
            calc_system_mass(system);

            // update sorbate info on each node
            if (system->sorbateCount > 1)
                update_sorbate_info(system);

/*write trajectory files for each node -> one at a time to avoid disk congestion*/
#ifdef MPI
            for (j = 0; j < size; j++) {
                MPI_Barrier(MPI_COMM_WORLD);
                if (j == rank) write_states(system);
            }
#else
            write_states(system);
#endif

            /*restart files for each node -> one at a time to avoid disk congestion*/
            if (write_molecules_wrapper(system, system->pqr_restart) < 0) {
                error(
                    "MC: could not write restart state to disk\n");
                return (-1);
            }

/*dipole/field data for each node -> one at a time to avoid disk congestion*/
#ifdef MPI
            if (system->polarization) {
                for (j = 0; j < size; j++) {
                    MPI_Barrier(MPI_COMM_WORLD);
                    if (j == rank) {
                        write_dipole(system);
                        write_field(system);
                    }
                }
            }
#else
            if (system->polarization) {
                write_dipole(system);
                write_field(system);
            }
#endif

            /* zero the send buffer */
            memset(snd_strct, 0, msgsize);
            memcpy(snd_strct, system->observables, sizeof(observables_t));
            memcpy(snd_strct + sizeof(observables_t), system->avg_nodestats, sizeof(avg_nodestats_t));
            if (system->calc_hist)
                mpi_copy_histogram_to_sendbuffer(snd_strct + sizeof(observables_t) + sizeof(avg_nodestats_t),
                                                 system->grids->histogram->grid, system);
            if (system->sorbateCount > 1)
                memcpy(snd_strct + sizeof(observables_t) + sizeof(avg_nodestats_t) + (system->calc_hist) * system->n_histogram_bins * sizeof(int),  //compensate for the size of hist data, if neccessary
                       system->sorbateInfo,
                       system->sorbateCount * sizeof(sorbateInfo_t));

            if (!rank) memset(rcv_strct, 0, size * msgsize);

#ifdef MPI
            MPI_Gather(snd_strct, 1, msgtype, rcv_strct, 1, msgtype, 0, MPI_COMM_WORLD);
            MPI_Gather(&(system->temperature), 1, MPI_DOUBLE, temperature_mpi, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
//need to gather shit for sorbate stats also
#else
            memcpy(rcv_strct, snd_strct, msgsize);
            temperature_mpi[0] = system->temperature;
#endif /* MPI */
            /* head node collects all observables and averages */
            if (!rank) {
                /* clear avg_nodestats to avoid double-counting */
                clear_avg_nodestats(system);
                //loop for each core -> shift data into variable_mpi, then average into avg_observables
                for (j = 0; j < size; j++) {
                    /* copy from the mpi buffer */
                    memcpy(observables_mpi, rcv_strct + j * msgsize, sizeof(observables_t));
                    memcpy(avg_nodestats_mpi, rcv_strct + j * msgsize + sizeof(observables_t), sizeof(avg_nodestats_t));
                    if (system->calc_hist)
                        mpi_copy_rcv_histogram_to_data(rcv_strct + j * msgsize + sizeof(observables_t) + sizeof(avg_nodestats_t), system->grids->histogram->grid, system);
                    if (system->sorbateCount > 1)
                        memcpy(sinfo_mpi,
                               rcv_strct + j * msgsize + sizeof(observables_t) + sizeof(avg_nodestats_t) + (system->calc_hist) * system->n_histogram_bins * sizeof(int),  //compensate for the size of hist data, if neccessary
                               system->sorbateCount * sizeof(sorbateInfo_t));

                    /* write observables */
                    if (system->file_pointers.fp_energy)
                        write_observables(system->file_pointers.fp_energy, system, observables_mpi, temperature_mpi[j]);
                    if (system->file_pointers.fp_energy_csv)
                        write_observables_csv(system->file_pointers.fp_energy_csv, system, observables_mpi, temperature_mpi[j]);
                    if (system->file_pointers.fp_xyz) {
                        write_molecules_xyz(system, system->file_pointers.fp_xyz);  //L
                    }
                    /* collect the averages */
                    /* if parallel tempering, we will collect obserables from the coldest bath. this can't be done for
					 * nodestats though, since nodestats are averaged over each corrtime, rather than based on a single 
					 * taken at the corrtime */
                    update_root_nodestats(system, avg_nodestats_mpi, system->avg_observables);
                    if (!system->parallel_tempering) {
                        update_root_averages(system, observables_mpi, system->avg_observables);
                        if (system->calc_hist) update_root_histogram(system);
                        if (system->sorbateCount > 1) update_root_sorb_averages(system, sinfo_mpi);
                    } else if (system->ptemp->index[j] == 0) {
                        update_root_averages(system, observables_mpi, system->avg_observables);
                        if (system->calc_hist) update_root_histogram(system);
                        if (system->sorbateCount > 1) update_root_sorb_averages(system, sinfo_mpi);
                    }
                }

                /* write the averages to stdout */
                if (system->file_pointers.fp_histogram)
                    write_histogram(system->file_pointers.fp_histogram, system->grids->avg_histogram->grid, system);

                if (write_performance(system->step, system) < 0) {
                    error(
                        "MC: could not write performance data to stdout\n");
                    return (-1);
                }
                if (write_averages(system) < 0) {
                    error(
                        "MC: could not write statistics to stdout\n");
                    return (-1);
                }

            } /* !rank */
        }     /* corrtime */
    }         /* main loop */

    /* write output, close any open files */
    free(snd_strct);

    // restart files for each node
    if (write_molecules_wrapper(system, system->pqr_output) < 0) {
        error(
            "MC: could not write final state to disk\n");
        return (-1);
    }

    if (!rank) {
        close_files(system);
        free(rcv_strct);
        free(temperature_mpi);
    }

    if (system->sorbateCount > 1) {
        free(system->sorbateGlobal);
        free(sinfo_mpi);
    }

    free(observables_mpi);
    free(avg_nodestats_mpi);

    printf(
        "MC: Total auto-rejected moves: %i\n", system->count_autorejects);

    return (0);
}