krb5_error_code
decode_krb5_tgs_req(const krb5_data *code, krb5_kdc_req **repptr)
{
    setup_no_length(krb5_kdc_req *);
    alloc_field(rep);
    clear_field(rep,padata);
    clear_field(rep,client);
    clear_field(rep,server);
    clear_field(rep,ktype);
    clear_field(rep,addresses);
    clear_field(rep,authorization_data.ciphertext.data);
    clear_field(rep,unenc_authdata);
    clear_field(rep,second_ticket);
    clear_field(rep, kdc_state);

    check_apptag(12);
    retval = asn1_decode_kdc_req(&buf,rep);
    if (retval) clean_return(retval);
#ifdef KRB5_MSGTYPE_STRICT
    if (rep->msg_type != KRB5_TGS_REQ) clean_return(KRB5_BADMSGTYPE);
#endif

    cleanup_manual();
error_out:
    krb5_free_kdc_req(NULL, rep);
    return retval;
}
Esempio n. 2
0
static int start()
{
	image_set_threshold_y(40);
	field1 = field;
	field2 = field + video_area;
	clear_field();

	stat = 1;
	return 0;
}
Esempio n. 3
0
static int event(SDL_Event *event)
{
	if(event->type == SDL_KEYDOWN) {
		switch(event->key.keysym.sym) {
		case SDLK_SPACE:
			clear_field();
			break;
		default:
			break;
		}
	}
	return 0;
}
krb5_error_code
decode_krb5_pa_fx_fast_request(const krb5_data *code, krb5_fast_armored_req **repptr)
{
    setup(krb5_fast_armored_req *);
    alloc_field(rep);
    clear_field(rep, armor);
    {
        int indef;
        unsigned int taglen;
        next_tag_from_buf(buf);
        if (tagnum != 0)
            clean_return(ASN1_BAD_ID);
    }
    {begin_structure();
        opt_field(rep->armor, 0, asn1_decode_fast_armor_ptr);
        get_field(rep->req_checksum, 1, asn1_decode_checksum);
        get_field(rep->enc_part, 2, asn1_decode_encrypted_data);
        end_structure();}
    rep->magic = KV5M_FAST_ARMORED_REQ;
    cleanup(free);
}
krb5_error_code
decode_krb5_fast_req(const krb5_data *code, krb5_fast_req **repptr)
{
    setup(krb5_fast_req *);
    alloc_field(rep);
    alloc_field(rep->req_body);
    clear_field(rep, req_body->padata);
    {begin_structure();
        get_field(rep->fast_options, 0, asn1_decode_krb5_flags);
        opt_field(rep->req_body->padata, 1, asn1_decode_sequence_of_pa_data);
        get_field(*(rep->req_body), 2, asn1_decode_kdc_req_body);
        end_structure(); }
    rep->magic  = KV5M_FAST_REQ;
    cleanup_manual();
error_out:
    if (rep) {
        if (rep->req_body)
            krb5_free_kdc_req(0, rep->req_body);
        free(rep);
    }
    return retval;
}
Esempio n. 6
0
void init_field(int n_d, int *n, double *L, field_info *FFT) {
    ptrdiff_t  n_x_local;
    ptrdiff_t  i_x_start_local;
    ptrdiff_t  n_y_transpose_local;
    ptrdiff_t  i_y_start_transpose_local;
    ptrdiff_t *n_x_rank;

    int  flag_active;
    int  n_active;
    int  min_size, max_size;

    SID_log("Initializing ", SID_LOG_OPEN);
    for(ptrdiff_t i_d = 0; i_d < n_d; i_d++) {
        if(i_d < (n_d - 1))
            SID_log("%dx", SID_LOG_CONTINUE, n[i_d]);
        else
            SID_log("%d element %d-d FFT ", SID_LOG_CONTINUE, n[i_d], n_d);
    }
    SID_log("(%d byte precision)...", SID_LOG_CONTINUE, (int)sizeof(GBPREAL));

    // Initialize FFT sizes
    FFT->n_d             = n_d;
    FFT->n               = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    FFT->L               = (double *)SID_calloc(sizeof(double) * FFT->n_d);
    FFT->n_k_local       = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    FFT->n_R_local       = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    FFT->i_R_start_local = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    FFT->i_k_start_local = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    FFT->i_R_stop_local  = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    FFT->i_k_stop_local  = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d);
    for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) {
        FFT->n[i_d]               = n[i_d];
        FFT->L[i_d]               = L[i_d];
        FFT->i_R_start_local[i_d] = 0;
        FFT->i_k_start_local[i_d] = 0;
        FFT->n_R_local[i_d]       = FFT->n[i_d];
        FFT->n_k_local[i_d]       = FFT->n[i_d];
    }
    FFT->n_k_local[FFT->n_d - 1] = FFT->n[FFT->n_d - 1] / 2 + 1;

    // Initialize FFTW

    // Create an integer version of FFT->n[] to pass to ..._create_plan
    int *n_int=(int *)SID_malloc(sizeof(int)*FFT->n_d);
    for(int i_d=0;i_d<FFT->n_d;i_d++)
        n_int[i_d]=(int)FFT->n[i_d];
#if FFTW_V2
#if USE_MPI
    int total_local_size_int;
    int n_x_local_int;
    int i_x_start_local_int;
    int n_y_transpose_local_int;
    int i_y_start_transpose_local_int;
    FFT->plan  = rfftwnd_mpi_create_plan(SID.COMM_WORLD->comm, FFT->n_d, n_int, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
    FFT->iplan = rfftwnd_mpi_create_plan(SID.COMM_WORLD->comm, FFT->n_d, n_int, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE);
    rfftwnd_mpi_local_sizes(FFT->plan,
                            &(n_x_local_int),
                            &(i_x_start_local_int),
                            &(n_y_transpose_local_int),
                            &(i_y_start_transpose_local_int),
                            &total_local_size_int);
    n_x_local =  (ptrdiff_t)n_x_local_int;
    i_x_start_local = (ptrdiff_t)i_x_start_local_int;
    n_y_transpose_local = (ptrdiff_t)n_y_transpose_local_int;
    i_y_start_transpose_local = (ptrdiff_t)i_y_start_transpose_local_int;
    FFT->total_local_size = (size_t)total_local_size_int;
#else
    FFT->total_local_size = 1;
    for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) {
        if(i_d < FFT->n_d - 1)
            FFT->total_local_size *= FFT->n[i_d];
        else
            FFT->total_local_size *= 2 * (FFT->n[i_d] / 2 + 1);
    }
#if USE_DOUBLE
    FFT->plan  = fftwnd_create_plan(FFT->n_d, n_int, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE | FFTW_IN_PLACE);
    FFT->iplan = fftwnd_create_plan(FFT->n_d, n_int, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE | FFTW_IN_PLACE);
#else
    FFT->plan  = rfftwnd_create_plan(FFT->n_d, n_int, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE | FFTW_IN_PLACE);
    FFT->iplan = rfftwnd_create_plan(FFT->n_d, n_int, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE | FFTW_IN_PLACE);
#endif
#endif
#else
#if USE_MPI
#if USE_DOUBLE
    fftw_mpi_init();
    FFT->total_local_size = fftw_mpi_local_size_many_transposed(FFT->n_d,
                                                                FFT->n,
                                                                1,
                                                                FFTW_MPI_DEFAULT_BLOCK,
                                                                FFTW_MPI_DEFAULT_BLOCK,
                                                                SID_COMM_WORLD->comm,
                                                                &(n_x_local),
                                                                &(i_x_start_local),
                                                                &(n_y_transpose_local),
                                                                &(i_y_start_transpose_local));
    FFT->plan  = fftw_mpi_plan_dft_r2c(FFT->n_d, FFT->n, FFT->field_local, FFT->cfield_local, SID_COMM_WORLD->comm, FFTW_ESTIMATE);
    FFT->iplan = fftw_mpi_plan_dft_c2r(FFT->n_d, FFT->n, FFT->cfield_local, FFT->field_local, SID_COMM_WORLD->comm, FFTW_ESTIMATE);
#else
    fftwf_mpi_init();
    FFT->total_local_size   = fftwf_mpi_local_size_many_transposed(FFT->n_d,
                                                                 FFT->n,
                                                                 1,
                                                                 FFTW_MPI_DEFAULT_BLOCK,
                                                                 FFTW_MPI_DEFAULT_BLOCK,
                                                                 SID_COMM_WORLD->comm,
                                                                 &(n_x_local),
                                                                 &(i_x_start_local),
                                                                 &(n_y_transpose_local),
                                                                 &(i_y_start_transpose_local));
    FFT->plan  = fftwf_mpi_plan_dft_r2c(FFT->n_d, FFT->n, FFT->field_local, FFT->cfield_local, SID_COMM_WORLD->comm, FFTW_ESTIMATE);
    FFT->iplan = fftwf_mpi_plan_dft_c2r(FFT->n_d, FFT->n, FFT->cfield_local, FFT->field_local, SID_COMM_WORLD->comm, FFTW_ESTIMATE);
#endif
#else
    FFT->total_local_size = 1;
    for(ptrdiff_t i_d=0; i_d < FFT->n_d; i_d++) {
        if(i_d < FFT->n_d - 1)
            FFT->total_local_size *= FFT->n[i_d];
        else
            FFT->total_local_size *= 2 * (FFT->n[i_d] / 2 + 1);
    }
#if USE_DOUBLE
    FFT->plan  = fftw_plan_dft_r2c(FFT->n_d, FFT->n, FFT->field_local, FFT->cfield_local, FFTW_ESTIMATE);
    FFT->iplan = fftw_plan_dft_c2r(FFT->n_d, FFT->n, FFT->cfield_local, FFT->field_local, FFTW_ESTIMATE);
#else
    FFT->plan  = fftwf_plan_dft_r2c(FFT->n_d, FFT->n, FFT->field_local, FFT->cfield_local, FFTW_ESTIMATE);
    FFT->iplan = fftwf_plan_dft_c2r(FFT->n_d, FFT->n, FFT->cfield_local, FFT->field_local, FFTW_ESTIMATE);
#endif
#endif
#endif

    SID_free(SID_FARG n_int);


    // Set empty slabs to start at 0 to make ignoring them simple.
    if(n_x_local == 0)
        i_x_start_local = 0;
    if(n_y_transpose_local == 0)
        i_y_start_transpose_local = 0;

    // Modify the local slab dimensions according to what FFTW chose.
    FFT->i_R_start_local[0] = i_x_start_local;
    FFT->n_R_local[0]       = n_x_local;
    if(FFT->n_d > 1) {
        FFT->i_k_start_local[1] = i_y_start_transpose_local;
        FFT->n_k_local[1]       = n_y_transpose_local;
    }

    // Allocate field
#if USE_FFTW3
    FFT->field_local  = (gbpFFT_real    *)fftwf_alloc_real(FFT->total_local_size);
#else
    FFT->field_local  = (gbpFFT_real    *)SID_malloc(sizeof(gbpFFT_real)*FFT->total_local_size);
#endif
    FFT->cfield_local = (gbpFFT_complex *)FFT->field_local;

    // Upper limits of slab decomposition
    for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) {
        FFT->i_R_stop_local[i_d] = FFT->i_R_start_local[i_d] + FFT->n_R_local[i_d] - 1;
        FFT->i_k_stop_local[i_d] = FFT->i_k_start_local[i_d] + FFT->n_k_local[i_d] - 1;
    }

    // FFTW padding sizes
    if(FFT->n_d > 1) {
        FFT->pad_size_R = 2 * (FFT->n_R_local[FFT->n_d - 1] / 2 + 1) - FFT->n_R_local[FFT->n_d - 1];
        FFT->pad_size_k = 0;
    } else {
        FFT->pad_size_R = 0;
        FFT->pad_size_k = 0;
    }

    // Number of elements (global and local) in the FFT
    ptrdiff_t i_d = 0;
    for(FFT->n_field = 1, FFT->n_field_R_local = 1, FFT->n_field_k_local = 1; i_d < FFT->n_d; i_d++) {
        FFT->n_field *= (size_t)FFT->n[i_d];
        FFT->n_field_R_local *= (size_t)FFT->n_R_local[i_d];
        FFT->n_field_k_local *= (size_t)FFT->n_k_local[i_d];
    }

    // Clear the field
    clear_field(FFT);

    // Initialize the FFT's real-space grid
    FFT->R_field = (double **)SID_malloc(sizeof(double *) * FFT->n_d);
    FFT->dR      = (double *)SID_malloc(sizeof(double *) * FFT->n_d);
    for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) {
        FFT->R_field[i_d] = (double *)SID_malloc(sizeof(double) * (FFT->n[i_d] + 1));
        FFT->dR[i_d]      = FFT->L[i_d] / (double)(FFT->n[i_d]);
        for(ptrdiff_t i_i = 0; i_i < FFT->n[i_d]; i_i++)
            FFT->R_field[i_d][i_i] = FFT->L[i_d] * ((double)i_i / (double)(FFT->n[i_d]));
        FFT->R_field[i_d][FFT->n[i_d]] = FFT->L[i_d];
    }

    // Initialize the FFT's k-space grid
    FFT->k_field   = (double **)SID_malloc(sizeof(double *) * FFT->n_d);
    FFT->dk        = (double *)SID_malloc(sizeof(double *) * FFT->n_d);
    FFT->k_Nyquist = (double *)SID_malloc(sizeof(double *) * FFT->n_d);
    for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) {
        FFT->k_field[i_d]   = (double *)SID_malloc(sizeof(double) * FFT->n[i_d]);
        FFT->dk[i_d]        = TWO_PI / FFT->L[i_d];
        FFT->k_Nyquist[i_d] = TWO_PI * (double)(FFT->n[i_d]) / FFT->L[i_d] / 2.;
        for(ptrdiff_t i_i = 0; i_i < FFT->n[i_d]; i_i++) {
            if(i_i >= FFT->n[i_d] / 2)
                FFT->k_field[i_d][i_i] = TWO_PI * (double)(i_i - FFT->n[i_d]) / FFT->L[i_d];
            else
                FFT->k_field[i_d][i_i] = TWO_PI * (double)(i_i) / FFT->L[i_d];
        }
    }

    // Flags
    FFT->flag_padded = GBP_FALSE;

    // Slab info
    FFT->slab.n_x_local       = FFT->n_R_local[0];
    FFT->slab.i_x_start_local = FFT->i_R_start_local[0];
    FFT->slab.i_x_stop_local  = FFT->i_R_stop_local[0];
    FFT->slab.x_min_local     = FFT->R_field[0][FFT->i_R_start_local[0]];
    if(FFT->slab.n_x_local > 0)
        FFT->slab.x_max_local = FFT->R_field[0][FFT->i_R_stop_local[0] + 1];
    else
        FFT->slab.x_max_local = FFT->slab.x_min_local;
    SID_Allreduce(&(FFT->slab.x_max_local), &(FFT->slab.x_max), 1, SID_DOUBLE, SID_MAX, SID_COMM_WORLD);

#if USE_MPI
    // All ranks are not necessarily assigned any slices, so
    //   we need to figure out what ranks are to the right and the left for
    //   buffer exchanges
    n_x_rank              = (ptrdiff_t *)SID_malloc(sizeof(ptrdiff_t) * SID.n_proc);
    n_x_rank[SID.My_rank] = (ptrdiff_t)FFT->slab.n_x_local;
    if(n_x_rank[SID.My_rank] > 0)
        flag_active = GBP_TRUE;
    else
        flag_active = GBP_FALSE;
    SID_Allreduce(&flag_active, &n_active, 1, SID_INT, SID_SUM, SID_COMM_WORLD);
    SID_Allreduce(&n_x_rank[SID.My_rank], &min_size, 1, SID_INT, SID_MIN, SID_COMM_WORLD);
    SID_Allreduce(&n_x_rank[SID.My_rank], &max_size, 1, SID_INT, SID_MAX, SID_COMM_WORLD);
    for(int i_rank = 0; i_rank < SID.n_proc; i_rank++)
        SID_Bcast(&(n_x_rank[i_rank]), 1, SID_INT, i_rank, SID_COMM_WORLD);
    FFT->slab.rank_to_right = -1;
    for(int i_rank = SID.My_rank + 1; i_rank < SID.My_rank + SID.n_proc && FFT->slab.rank_to_right < 0; i_rank++) {
        int j_rank = i_rank % SID.n_proc;
        if(n_x_rank[j_rank] > 0)
            FFT->slab.rank_to_right = j_rank;
    }
    if(FFT->slab.rank_to_right < 0)
        FFT->slab.rank_to_right = SID.My_rank;
    FFT->slab.rank_to_left = -1;
    for(int i_rank = SID.My_rank - 1; i_rank > SID.My_rank - SID.n_proc && FFT->slab.rank_to_left < 0; i_rank--) {
        int j_rank = i_rank;
        if(i_rank < 0)
            j_rank = i_rank + SID.n_proc;
        if(n_x_rank[j_rank] > 0)
            FFT->slab.rank_to_left = j_rank;
    }
    if(FFT->slab.rank_to_left < 0)
        FFT->slab.rank_to_left = SID.My_rank;
    free(n_x_rank);
    SID_log("(%d cores unused, min/max slab size=%d/%d)...", SID_LOG_CONTINUE, SID.n_proc - n_active, min_size, max_size);
#else
    FFT->slab.rank_to_right = SID.My_rank;
    FFT->slab.rank_to_left  = SID.My_rank;
    if(FFT->slab.n_x_local > 0) {
        flag_active = GBP_TRUE;
        n_active    = 1;
        min_size    = FFT->slab.n_x_local;
        max_size    = FFT->slab.n_x_local;
    } else {
        flag_active = GBP_FALSE;
        n_active    = 0;
        min_size    = 0;
        max_size    = 0;
    }
#endif

    SID_log("Done.", SID_LOG_CLOSE);
}
Esempio n. 7
0
void map_to_grid(size_t      n_particles_local,
                 GBPREAL *   x_particles_local,
                 GBPREAL *   y_particles_local,
                 GBPREAL *   z_particles_local,
                 GBPREAL *   v_particles_local,
                 GBPREAL *   w_particles_local,
                 cosmo_info *cosmo,
                 double      redshift,
                 int         distribution_scheme,
                 double      normalization_constant,
                 field_info *field,
                 field_info *field_norm,
                 int         mode) {
    size_t       i_p;
    int          i_k;
    size_t       i_b;
    size_t       i_grid;
    int          i_coord;
    int          i_i[3];
    int          j_i[3];
    int          k_i[3];
    size_t       n_particles;
    double       v_p;
    double       w_p;
    int          flag_valued_particles;
    int          flag_weight_particles;
    int          flag_weight;
    int          flag_active;
    int          flag_viable;
    double       k_mag;
    double       dk;
    int          n_powspec;
    int          mode_powspec;
    size_t *     n_mode_powspec;
    double *     k_powspec;
    double *     kmin_powspec;
    double *     kmax_powspec;
    double *     k_powspec_bin;
    double *     P_powspec;
    double *     dP_powspec;
    double       k_min;
    double       k_max;
    double       norm_local;
    double       normalization;
    GBPREAL      x_i;
    GBPREAL      x_particle_i;
    GBPREAL      y_particle_i;
    GBPREAL      z_particle_i;
    double       kernal_offset;
    int          W_search_lo;
    int          W_search_hi;
    size_t       receive_left_size  = 0;
    size_t       receive_right_size = 0;
    size_t       index_best;
    int          n_buffer[3];
    size_t       n_send_left;
    size_t       n_send_right;
    size_t       send_size_left;
    size_t       send_size_right;
    GBPREAL *    send_left          = NULL;
    GBPREAL *    send_right         = NULL;
    GBPREAL *    receive_left       = NULL;
    GBPREAL *    receive_right      = NULL;
    GBPREAL *    send_left_norm     = NULL;
    GBPREAL *    send_right_norm    = NULL;
    GBPREAL *    receive_left_norm  = NULL;
    GBPREAL *    receive_right_norm = NULL;
    double       r_i, r_min, r_i_max = 0;
    double       W_i;
    int          index_i;
    interp_info *P_k_interp;
    double *     r_Daub;
    double *     W_Daub;
    double       h_Hubble;
    int          n_Daub;
    interp_info *W_r_Daub_interp = NULL;
    int          i_rank;
    size_t       buffer_index;
    int          i_test;
    double       accumulator;

    // Compute the total poulation size and print a status message
    calc_sum_global(&n_particles_local, &n_particles, 1, SID_SIZE_T, CALC_MODE_DEFAULT, SID_COMM_WORLD);
    SID_log("Distributing %zu items onto a %dx%dx%d grid...", SID_LOG_OPEN, n_particles, field->n[0], field->n[1], field->n[2]);

    // If we've been given a normalization field, make sure it's got the same geometry as the results field
    if(field_norm != NULL) {
        if(field->n_d != field_norm->n_d)
            SID_exit_error("grid dimension counts don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->n_d,
                           field_norm->n_d);
        int i_d;
        for(i_d = 0; i_d < field->n_d; i_d++) {
            if(field->n[i_d] != field_norm->n[i_d])
                SID_exit_error("grid dimension No. %d's sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, i_d,
                               field->n[i_d], field_norm->n[i_d]);
            if(field->n_R_local[i_d] != field_norm->n_R_local[i_d])
                SID_exit_error("grid dimension No. %d's slab sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, i_d,
                               field->n_R_local[i_d], field_norm->n_R_local[i_d]);
            if(field->i_R_start_local[i_d] != field_norm->i_R_start_local[i_d])
                SID_exit_error("grid dimension No. %d's start positions don't match (ie. %le!=%le)", SID_ERROR_LOGIC,
                               i_d, field->i_R_start_local[i_d], field_norm->i_R_start_local[i_d]);
            if(field->i_R_stop_local[i_d] != field_norm->i_R_stop_local[i_d])
                SID_exit_error("grid dimension No. %d's stop positions don't match (ie. %le!=%le)", SID_ERROR_LOGIC,
                               i_d, field->i_R_stop_local[i_d], field_norm->i_R_stop_local[i_d]);
        }
        if(field->n_field != field_norm->n_field)
            SID_exit_error("grid field sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->n_field,
                           field_norm->n_field);
        if(field->n_field_R_local != field_norm->n_field_R_local)
            SID_exit_error("grid local field sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->n_field_R_local,
                           field_norm->n_field_R_local);
        if(field->total_local_size != field_norm->total_local_size)
            SID_exit_error("grid total local sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->total_local_size,
                           field_norm->total_local_size);
    }

    // Set some variables
    if(v_particles_local != NULL)
        flag_valued_particles = GBP_TRUE;
    else {
        flag_valued_particles = GBP_FALSE;
        v_p                   = 1.;
    }
    if(w_particles_local != NULL)
        flag_weight_particles = GBP_TRUE;
    else {
        flag_weight_particles = GBP_FALSE;
        w_p                   = 1.;
    }
    h_Hubble = ((double *)ADaPS_fetch(cosmo, "h_Hubble"))[0];

    // Initializing the mass assignment scheme
    switch(distribution_scheme) {
        case MAP2GRID_DIST_DWT20:
            W_search_lo   = 2;
            W_search_hi   = 7;
            kernal_offset = 2.5;
            compute_Daubechies_scaling_fctns(20, 5, &r_Daub, &W_Daub, &n_Daub);
            init_interpolate(r_Daub, W_Daub, n_Daub, gsl_interp_cspline, &W_r_Daub_interp);
            SID_free(SID_FARG r_Daub);
            SID_free(SID_FARG W_Daub);
            SID_log("(using D20 scale function kernal)...", SID_LOG_CONTINUE);
            break;
        case MAP2GRID_DIST_DWT12:
            W_search_lo   = 1;
            W_search_hi   = 6;
            kernal_offset = 1.75;
            compute_Daubechies_scaling_fctns(12, 5, &r_Daub, &W_Daub, &n_Daub);
            init_interpolate(r_Daub, W_Daub, (size_t)n_Daub, gsl_interp_cspline, &W_r_Daub_interp);
            SID_free(SID_FARG r_Daub);
            SID_free(SID_FARG W_Daub);
            SID_log("(using D12 scale function kernal)...", SID_LOG_CONTINUE);
            break;
        case MAP2GRID_DIST_TSC:
            W_search_lo = 2;
            W_search_hi = 2;
            SID_log("(using triangular shaped function kernal)...", SID_LOG_CONTINUE);
            break;
        case MAP2GRID_DIST_CIC:
            SID_log("(using cloud-in-cell kernal)...", SID_LOG_CONTINUE);
        case MAP2GRID_DIST_NGP:
        default:
            W_search_lo = 1;
            W_search_hi = 1;
            SID_log("(using nearest grid point kernal)...", SID_LOG_CONTINUE);
            break;
    }

    // Initializing slab buffers
    n_send_left     = (size_t)(field->n[0] * field->n[1] * W_search_lo);
    n_send_right    = (size_t)(field->n[0] * field->n[1] * W_search_hi);
    send_size_left  = n_send_left * sizeof(GBPREAL);
    send_size_right = n_send_right * sizeof(GBPREAL);
    send_left       = (GBPREAL *)SID_calloc(send_size_left);
    send_right      = (GBPREAL *)SID_calloc(send_size_right);
    receive_left    = (GBPREAL *)SID_calloc(send_size_right);
    receive_right   = (GBPREAL *)SID_calloc(send_size_left);
    if(field_norm != NULL) {
        send_left_norm     = (GBPREAL *)SID_calloc(send_size_left);
        send_right_norm    = (GBPREAL *)SID_calloc(send_size_right);
        receive_left_norm  = (GBPREAL *)SID_calloc(send_size_right);
        receive_right_norm = (GBPREAL *)SID_calloc(send_size_left);
    }

    // Clear the field
    if(!SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_NOCLEAN)) {
        SID_log("Clearing fields...", SID_LOG_OPEN);
        clear_field(field);
        if(field_norm != NULL)
            clear_field(field);
        SID_log("Done.", SID_LOG_CLOSE);
    }

    // It is essential that we not pad the field for the simple way that we add-in the boundary buffers below
    set_FFT_padding_state(field, GBP_FALSE);
    if(field_norm != NULL)
        set_FFT_padding_state(field_norm, GBP_FALSE);

    // Create the mass distribution
    SID_log("Performing grid assignment...", SID_LOG_OPEN | SID_LOG_TIMER);

    // Loop over all the objects
    pcounter_info pcounter;
    SID_Init_pcounter(&pcounter, n_particles_local, 10);
    for(i_p = 0, norm_local = 0.; i_p < n_particles_local; i_p++) {
        double norm_i;
        double value_i;
        if(flag_valued_particles)
            v_p = (double)(v_particles_local[i_p]);
        if(flag_weight_particles)
            w_p = (double)(w_particles_local[i_p]);
        norm_i  = w_p;
        value_i = v_p * norm_i;

        // Particle's position
        x_particle_i = (GBPREAL)x_particles_local[i_p];
        y_particle_i = (GBPREAL)y_particles_local[i_p];
        z_particle_i = (GBPREAL)z_particles_local[i_p];

        // Quantize it onto the grid
        x_particle_i /= (GBPREAL)field->dR[0];
        y_particle_i /= (GBPREAL)field->dR[1];
        z_particle_i /= (GBPREAL)field->dR[2];
        i_i[0] = (int)x_particle_i; // position in grid-coordinates
        i_i[1] = (int)y_particle_i; // position in grid-coordinates
        i_i[2] = (int)z_particle_i; // position in grid-coordinates

        // Apply the kernel
        flag_viable = GBP_TRUE;
        double x_i_effective;
        for(j_i[0] = -W_search_lo; j_i[0] <= W_search_hi; j_i[0]++) {
            for(j_i[1] = -W_search_lo; j_i[1] <= W_search_hi; j_i[1]++) {
                for(j_i[2] = -W_search_lo; j_i[2] <= W_search_hi; j_i[2]++) {
                    // Compute distance to each grid point being searched against ...
                    flag_active = GBP_TRUE;
                    for(i_coord = 0, W_i = 1.; i_coord < 3; i_coord++) {
                        switch(i_coord) {
                            case 0:
                                x_i = (GBPREAL)(i_i[0] + j_i[0]) - x_particle_i;
                                break;
                            case 1:
                                x_i = (GBPREAL)(i_i[1] + j_i[1]) - y_particle_i;
                                break;
                            case 2:
                                x_i = (GBPREAL)(i_i[2] + j_i[2]) - z_particle_i;
                                break;
                        }
                        switch(distribution_scheme) {
                                // Distribute with a Daubechies wavelet transform of 12th or 20th order a la Cui et al '08
                            case MAP2GRID_DIST_DWT12:
                            case MAP2GRID_DIST_DWT20:
                                x_i_effective = x_i + kernal_offset;
                                if(x_i_effective > 0.)
                                    W_i *= interpolate(W_r_Daub_interp, x_i_effective);
                                else
                                    flag_active = GBP_FALSE;
                                break;
                                // Distribute using the triangular shaped cloud (TSC) method
                            case MAP2GRID_DIST_TSC:
                                if(x_i < 0.5)
                                    W_i *= (0.75 - x_i * x_i);
                                else if(x_i < 1.5)
                                    W_i *= 0.5 * (1.5 - fabs(x_i)) * (1.5 - fabs(x_i));
                                else
                                    flag_active = GBP_FALSE;
                                break;
                                // Distribute using the cloud-in-cell (CIC) method
                            case MAP2GRID_DIST_CIC:
                                if(fabs(x_i) < 1.)
                                    W_i *= (1. - fabs(x_i));
                                else
                                    flag_active = GBP_FALSE;
                                break;
                                // Distribute using "nearest grid point" (NGP; ie. the simplest and default) method
                            case MAP2GRID_DIST_NGP:
                            default:
                                if(fabs(x_i) <= 0.5 && flag_viable)
                                    W_i *= 1.;
                                else
                                    flag_active = GBP_FALSE;
                                break;
                        }
                    }
                    if(flag_active) { // This flags-out regions of the kernal with no support to save some time
                        // Set the grid indices (enforce periodic BCs; do x-coordinate last) ...
                        //   ... y-coordinate ...
                        k_i[1] = (i_i[1] + j_i[1]);
                        if(k_i[1] < 0)
                            k_i[1] += field->n[1];
                        else
                            k_i[1] = k_i[1] % field->n[1];
                        //   ... z-coordinate ...
                        k_i[2] = i_i[2] + j_i[2];
                        if(k_i[2] < 0)
                            k_i[2] += field->n[2];
                        else
                            k_i[2] = k_i[2] % field->n[2];
                        //   ... x-coordinate ...
                        //     Depending on x-index, add contribution to the
                        //     local array or to the slab buffers.
                        k_i[0] = (i_i[0] + j_i[0]);
                        if(k_i[0] < field->i_R_start_local[0]) {
                            k_i[0] -= (field->i_R_start_local[0] - W_search_lo);
                            if(k_i[0] < 0)
                                SID_exit_error("Left slab buffer limit exceeded by %d element(s).", SID_ERROR_LOGIC,
                                               -k_i[0]);
                            send_left[index_FFT_R(field, k_i)] += W_i * value_i;
                            if(field_norm != NULL)
                                send_left_norm[index_FFT_R(field_norm, k_i)] += W_i * norm_i;
                        } else if(k_i[0] > field->i_R_stop_local[0]) {
                            k_i[0] -= (field->i_R_stop_local[0] + 1);
                            if(k_i[0] >= W_search_hi)
                                SID_exit_error("Right slab buffer limit exceeded by %d element(s).", SID_ERROR_LOGIC,
                                               k_i[0] - W_search_hi + 1);
                            else {
                                send_right[index_FFT_R(field, k_i)] += W_i * value_i;
                                if(field_norm != NULL)
                                    send_right_norm[index_FFT_R(field_norm, k_i)] += W_i * norm_i;
                            }
                        } else {
                            field->field_local[index_local_FFT_R(field, k_i)] += W_i * value_i;
                            if(field_norm != NULL)
                                field_norm->field_local[index_local_FFT_R(field_norm, k_i)] += W_i * norm_i;
                        }
                        flag_viable = GBP_FALSE;
                    }
                }
            }
        }
        // Report the calculation's progress
        SID_check_pcounter(&pcounter, i_p);
    }
    SID_log("Done.", SID_LOG_CLOSE);

    // Perform exchange of slab buffers and add them to the local mass distribution.
    //    Note: it's important that the FFT field not be padded (see above, where
    //          this is set) for this to work the way it's done.
    SID_log("Adding-in the slab buffers...", SID_LOG_OPEN | SID_LOG_TIMER);
    // Numerator first ...
    exchange_slab_buffer_left(send_left, send_size_left, receive_right, &receive_right_size, &(field->slab));
    exchange_slab_buffer_right(send_right, send_size_right, receive_left, &receive_left_size, &(field->slab));
    for(i_b = 0; i_b < n_send_right; i_b++)
        field->field_local[i_b] += receive_left[i_b];
    for(i_b = 0; i_b < n_send_left; i_b++)
        field->field_local[field->n_field_R_local - n_send_left + i_b] += receive_right[i_b];
    // ... then denominator (if it's being used)
    if(field_norm != NULL) {
        exchange_slab_buffer_left(send_left_norm, send_size_left, receive_right_norm, &receive_right_size, &(field_norm->slab));
        exchange_slab_buffer_right(send_right_norm, send_size_right, receive_left_norm, &receive_left_size, &(field_norm->slab));
        for(i_b = 0; i_b < n_send_right; i_b++)
            field_norm->field_local[i_b] += receive_left_norm[i_b];
        for(i_b = 0; i_b < n_send_left; i_b++)
            field_norm->field_local[field_norm->n_field_R_local - n_send_left + i_b] += receive_right[i_b];
    }
    SID_free(SID_FARG send_left);
    SID_free(SID_FARG send_right);
    SID_free(SID_FARG receive_left);
    SID_free(SID_FARG receive_right);
    if(field_norm != NULL) {
        SID_free(SID_FARG send_left_norm);
        SID_free(SID_FARG send_right_norm);
        SID_free(SID_FARG receive_left_norm);
        SID_free(SID_FARG receive_right_norm);
    }
    SID_log("Done.", SID_LOG_CLOSE);

    // Recompute local normalization (more accurate for large sample sizes)
    if(!SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_NONORM)) {
        SID_log("Applying normalization...", SID_LOG_OPEN);
        if(field_norm != NULL) {
            for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++) {
                if(field_norm->field_local[i_grid] != 0)
                    field->field_local[i_grid] /= field_norm->field_local[i_grid];
            }
        }
        if(SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_APPLYFACTOR)) {
            for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++)
                field->field_local[i_grid] *= normalization_constant;
        }
        if(SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_FORCENORM)) {
            norm_local = 0;
            for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++)
                norm_local += (double)field->field_local[i_grid];
            calc_sum_global(&norm_local, &normalization, 1, SID_DOUBLE, CALC_MODE_DEFAULT, SID_COMM_WORLD);
            double normalization_factor;
            normalization_factor = normalization_constant / normalization;
            for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++)
                field->field_local[i_grid] *= normalization_factor;
        }
        SID_log("Done.", SID_LOG_CLOSE, normalization);
    }

    if(W_r_Daub_interp != NULL)
        free_interpolate(SID_FARG W_r_Daub_interp, NULL);

    SID_log("Done.", SID_LOG_CLOSE);
}
Esempio n. 8
0
void init_field() {
    clear_field();
    find_crossings();
}