[cig-commits] r6666 - cs/cigma/trunk/sandbox/c
luis at geodynamics.org
luis at geodynamics.org
Tue Apr 24 14:59:03 PDT 2007
Author: luis
Date: 2007-04-24 14:59:03 -0700 (Tue, 24 Apr 2007)
New Revision: 6666
Added:
cs/cigma/trunk/sandbox/c/qr.c
cs/cigma/trunk/sandbox/c/qr.h
Log:
Provide three ways to specify the quadrature rules (from a text file,
from an hdf5 file, or directly from an array)
Added: cs/cigma/trunk/sandbox/c/qr.c
===================================================================
--- cs/cigma/trunk/sandbox/c/qr.c 2007-04-24 21:52:29 UTC (rev 6665)
+++ cs/cigma/trunk/sandbox/c/qr.c 2007-04-24 21:59:03 UTC (rev 6666)
@@ -0,0 +1,189 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "qr.h"
+#include "hdf5.h"
+
+
+static int qr_init1_read_weights(rule_t *qr, hid_t dset_id);
+static int qr_init1_read_points(rule_t *qr, hid_t dset_id);
+
+
+int qr_fini(rule_t *qr)
+{
+ free(qr->weights);
+ free(qr->points);
+ return 0;
+}
+
+int qr_init0(rule_t *qr, char *filename)
+{
+ int q, nq;
+ int i, n;
+
+ FILE *fp;
+ int ret;
+
+ fp = fopen(filename, "r");
+ if (fp == NULL)
+ {
+ return -1;
+ }
+
+ ret = fscanf(fp, "%d", &nq);
+ ret = fscanf(fp, "%d", &n);
+
+ qr->nq = nq;
+ qr->n = n;
+ qr->weights = (double *)malloc(nq * sizeof(double));
+ qr->points = (double *)malloc(nq * n * sizeof(double));
+
+ for (q = 0; q < nq; q++)
+ {
+ ret = fscanf(fp, "%lf", &(qr->weights[q]));
+ for (i = 0; i < n; i++)
+ {
+ ret = fscanf(fp, "%lf", &(qr->points[n*q + i]));
+ }
+ }
+
+ fclose(fp);
+ return 0;
+}
+
+int qr_init1(rule_t *qr, char *filename, char *path)
+{
+ hid_t file_id;
+ hid_t group_id;
+ hid_t weights_dset;
+ hid_t points_dset;
+
+ herr_t status;
+ int ierr;
+
+ /* for now, zero out n & nq */
+ qr->nq = 0;
+ qr->n = 0;
+
+ /* open the file in read-only mode */
+ file_id = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
+ if (file_id < 0)
+ {
+ return -1;
+ }
+
+ /* open group at specified path */
+ group_id = H5Gopen(file_id, path);
+ if (group_id < 0)
+ {
+ H5Fclose(file_id);
+ return -2;
+ }
+
+ /* read quadrature weights */
+ weights_dset = H5Dopen(group_id, "weights");
+ ierr = qr_init1_read_weights(qr, weights_dset);
+ status = H5Dclose(weights_dset);
+
+ /* read quadrature points */
+ points_dset = H5Dopen(group_id, "points");
+ ierr = qr_init1_read_points(qr, points_dset);
+ status = H5Dclose(points_dset);
+
+ /* finalize */
+ status = H5Gclose(group_id);
+ status = H5Fclose(file_id);
+
+ return 0;
+}
+
+
+void qr_apply(rule_t *qr, double (*f)(double *), double *sum)
+{
+ int q; // for looping over quadrature points
+ int nq = qr->nq; // number of quadrature points
+ int n = qr->n; // dimension of points
+
+ double *x = qr->points;
+ double *w = qr->weights;
+ double acc = 0.0;
+
+ for (q = 0; q < nq; q++)
+ acc += w[q] * f(&x[q*n]);
+
+ *sum = acc;
+}
+
+
+
+/*
+ * Private functions
+ */
+
+static int qr_init1_read_weights(rule_t *qr, hid_t dset_id)
+{
+ herr_t status;
+ hid_t weights_dspace;
+ int rank;
+
+ weights_dspace = H5Dget_space(dset_id);
+
+ rank = H5Sget_simple_extent_ndims(weights_dspace);
+ if (rank != 1)
+ {
+ return -1; // error: expecting 1d array
+ }
+
+ if (qr->nq == 0)
+ {
+ qr->nq = H5Sget_simple_extent_npoints(weights_dspace);
+ }
+
+ status = H5Sclose(weights_dspace);
+
+ qr->weights = (double *)malloc((qr->nq) * sizeof(double));
+
+ status = H5Dread(dset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, qr->weights);
+
+ return 0;
+}
+
+static int qr_init1_read_points(rule_t *qr, hid_t dset_id)
+{
+ herr_t status;
+ hid_t points_dspace;
+ hsize_t npoints;
+ hsize_t *dims;
+ int rank;
+
+ points_dspace = H5Dget_space(dset_id);
+
+ rank = H5Sget_simple_extent_ndims(points_dspace);
+ if (rank != 2 && rank != 1)
+ {
+ return -1;
+ }
+
+ dims = (hsize_t *)malloc(rank * sizeof(hsize_t));
+ status = H5Sget_simple_extent_dims(points_dspace, dims, NULL);
+ npoints = H5Sget_simple_extent_npoints(points_dspace);
+ if (qr->nq != 0)
+ {
+ if (qr->nq != dims[0])
+ return -2;
+ }
+ else
+ {
+ qr->nq = dims[0];
+ qr->n = (rank > 1) ? dims[1] : 1;
+ }
+
+ qr->points = (double *)malloc(npoints * sizeof(double));
+
+ status = H5Dread(dset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, qr->points);
+
+ free(dims);
+
+ return 0;
+}
Added: cs/cigma/trunk/sandbox/c/qr.h
===================================================================
--- cs/cigma/trunk/sandbox/c/qr.h 2007-04-24 21:52:29 UTC (rev 6665)
+++ cs/cigma/trunk/sandbox/c/qr.h 2007-04-24 21:59:03 UTC (rev 6666)
@@ -0,0 +1,24 @@
+#ifndef __CIGMA_QR_H__
+#define __CIGMA_QR_H__
+
+typedef struct
+{
+ int n;
+ int nq;
+ double *weights;
+ double *points;
+} rule_t;
+
+typedef void (*generator_t)(int, int, double *, double *);
+typedef double (*functor_t)(double *);
+
+int qr_init0(rule_t *qr, char *filename);
+int qr_init1(rule_t *qr, char *filename, char *path);
+int qr_init2(rule_t *qr, generator_t gen);
+int qr_fini(rule_t *qr);
+
+void qr_get(rule_t *qr, double *w, double *x);
+
+void qr_apply(rule_t *qr, functor_t f, double *sum);
+
+#endif
More information about the cig-commits
mailing list