green_workspace * green_alloc(const size_t nmax) { green_workspace *w; size_t nnm_tot, array_size; w = calloc(1, sizeof(green_workspace)); if (!w) return 0; w->nmax = nmax; nnm_tot = (nmax + 1) * (nmax + 1); /* exclude the (0,0) coefficient */ w->nnm = nnm_tot - 1; w->dX = malloc(w->nnm * sizeof(double)); w->dY = malloc(w->nnm * sizeof(double)); w->dZ = malloc(w->nnm * sizeof(double)); if (!w->dX || !w->dY || !w->dZ) { green_free(w); fprintf(stderr, "green_alloc: failed to alloc X,Y,Z arrays\n"); return 0; } w->dX_ext = malloc(w->nnm * sizeof(double)); w->dY_ext = malloc(w->nnm * sizeof(double)); w->dZ_ext = malloc(w->nnm * sizeof(double)); if (!w->dX_ext || !w->dY_ext || !w->dZ_ext) { green_free(w); fprintf(stderr, "green_alloc: failed to alloc X_ext,Y_ext,Z_ext arrays\n"); return 0; } w->cosmphi = malloc((nmax + 1) * sizeof(double)); w->sinmphi = malloc((nmax + 1) * sizeof(double)); if (!w->cosmphi || !w->sinmphi) { green_free(w); fprintf(stderr, "green_alloc: failed to alloc sin/cos arrays\n"); return 0; } array_size = gsl_sf_legendre_array_n(nmax); w->Plm = malloc(array_size * sizeof(double)); w->dPlm = malloc(array_size * sizeof(double)); if (!w->Plm || !w->dPlm) { green_free(w); fprintf(stderr, "green_alloc: failed to alloc legendre arrays\n"); return 0; } return w; } /* green_alloc() */
mfield_green_workspace * mfield_green_alloc(const size_t nmax, const double R) { mfield_green_workspace *w; const size_t plm_size = gsl_sf_legendre_array_n(nmax); const size_t nnm_tot = (nmax + 1) * (nmax + 1); w = calloc(1, sizeof(mfield_green_workspace)); if (!w) return 0; w->nmax = nmax; w->nnm = nnm_tot - 1; /* exclude (0,0) coefficient */ w->R = R; w->cosmphi = malloc((nmax + 1) * sizeof(double)); w->sinmphi = malloc((nmax + 1) * sizeof(double)); if (!w->cosmphi || !w->sinmphi) { mfield_green_free(w); fprintf(stderr, "mfield_green_alloc: cannot allocate space for cos/sin arrays: %s\n", strerror(errno)); return 0; } w->Plm = malloc(plm_size * sizeof(double)); w->dPlm = malloc(plm_size * sizeof(double)); if (!w->Plm || !w->dPlm) { mfield_green_free(w); fprintf(stderr, "mfield_green_alloc: cannot allocate space for legendre arrays: %s\n", strerror(errno)); return 0; } w->dX = malloc(w->nnm * sizeof(double)); w->dY = malloc(w->nnm * sizeof(double)); w->dZ = malloc(w->nnm * sizeof(double)); w->dX_ext = malloc(w->nnm * sizeof(double)); w->dY_ext = malloc(w->nnm * sizeof(double)); w->dZ_ext = malloc(w->nnm * sizeof(double)); if (!w->dX || !w->dY || !w->dZ || !w->dX_ext || !w->dY_ext || !w->dZ_ext) { mfield_green_free(w); fprintf(stderr, "mfield_green_alloc: cannot allocate space for result arrays: %s\n", strerror(errno)); return 0; } return w; } /* mfield_green_alloc() */
CAMLprim value ml_gsl_sf_legendre_array(value norm, value vlmax, value m, value x, value result_array) { const size_t lmax = Int_val(vlmax); if (Double_array_length(result_array) < gsl_sf_legendre_array_n(lmax)) { caml_invalid_argument("Gsl_sf.legendre_array: array too small"); } gsl_sf_legendre_array(Int_val(norm), lmax, Double_val(x), Double_array_val(result_array)); return Val_unit; }