Updates to opennl for mesh laplacian matrix building, to make matrix

building with random access work together with variable locking.
This commit is contained in:
Brecht Van Lommel 2007-07-28 14:39:30 +00:00
parent 373f91c8b1
commit eb8ee6f568
2 changed files with 125 additions and 52 deletions

@ -131,10 +131,12 @@ void nlBegin(NLenum primitive);
void nlEnd(NLenum primitive); void nlEnd(NLenum primitive);
void nlCoefficient(NLuint index, NLfloat value); void nlCoefficient(NLuint index, NLfloat value);
/* Setting random elements matrix/vector - not for least squares! */ /* Setting random elements matrix/vector - not supported for
least squares! */
void nlMatrixAdd(NLuint row, NLuint col, NLfloat value); void nlMatrixAdd(NLuint row, NLuint col, NLfloat value);
void nlRightHandSideAdd(NLuint index, NLfloat value); void nlRightHandSideAdd(NLuint index, NLfloat value);
void nlRightHandSideSet(NLuint index, NLfloat value);
/* Solve */ /* Solve */

@ -441,6 +441,7 @@ typedef struct {
NLfloat value; NLfloat value;
NLboolean locked; NLboolean locked;
NLuint index; NLuint index;
__NLRowColumn *a;
} __NLVariable; } __NLVariable;
#define __NL_STATE_INITIAL 0 #define __NL_STATE_INITIAL 0
@ -453,13 +454,13 @@ typedef struct {
typedef struct { typedef struct {
NLenum state; NLenum state;
__NLVariable* variable;
NLuint n; NLuint n;
__NLVariable* variable;
NLfloat* b;
__NLSparseMatrix M; __NLSparseMatrix M;
__NLRowColumn af; __NLRowColumn af;
__NLRowColumn al; __NLRowColumn al;
NLfloat* x; NLfloat* x;
NLfloat* b;
NLfloat right_hand_side; NLfloat right_hand_side;
NLuint nb_variables; NLuint nb_variables;
NLuint current_row; NLuint current_row;
@ -472,8 +473,8 @@ typedef struct {
NLboolean alloc_variable; NLboolean alloc_variable;
NLboolean alloc_x; NLboolean alloc_x;
NLboolean alloc_b; NLboolean alloc_b;
NLfloat error; NLfloat error;
__NLMatrixFunc matrix_vector_prod; __NLMatrixFunc matrix_vector_prod;
struct __NLSuperLUContext { struct __NLSuperLUContext {
NLboolean alloc_slu; NLboolean alloc_slu;
@ -503,6 +504,8 @@ static void __nlFree_SUPERLU(__NLContext *context);
void nlDeleteContext(NLContext context_in) { void nlDeleteContext(NLContext context_in) {
__NLContext* context = (__NLContext*)(context_in); __NLContext* context = (__NLContext*)(context_in);
int i;
if(__nlCurrentContext == context) { if(__nlCurrentContext == context) {
__nlCurrentContext = NULL; __nlCurrentContext = NULL;
} }
@ -516,14 +519,19 @@ void nlDeleteContext(NLContext context_in) {
__nlRowColumnDestroy(&context->al); __nlRowColumnDestroy(&context->al);
} }
if(context->alloc_variable) { if(context->alloc_variable) {
__NL_DELETE_ARRAY(context->variable); for(i=0; i<context->nb_variables; i++) {
} if(context->variable[i].a) {
if(context->alloc_x) { __nlRowColumnDestroy(context->variable[i].a);
__NL_DELETE_ARRAY(context->x); __NL_DELETE(context->variable[i].a);
}
}
} }
if(context->alloc_b) { if(context->alloc_b) {
__NL_DELETE_ARRAY(context->b); __NL_DELETE_ARRAY(context->b);
} }
if(context->alloc_x) {
__NL_DELETE_ARRAY(context->x);
}
if (context->slu.alloc_slu) { if (context->slu.alloc_slu) {
__nlFree_SUPERLU(context); __nlFree_SUPERLU(context);
} }
@ -727,8 +735,10 @@ NLboolean nlVariableIsLocked(NLuint index) {
static void __nlVariablesToVector() { static void __nlVariablesToVector() {
NLuint i; NLuint i;
__nl_assert(__nlCurrentContext->alloc_x); __nl_assert(__nlCurrentContext->alloc_x);
__nl_assert(__nlCurrentContext->alloc_variable); __nl_assert(__nlCurrentContext->alloc_variable);
for(i=0; i<__nlCurrentContext->nb_variables; i++) { for(i=0; i<__nlCurrentContext->nb_variables; i++) {
__NLVariable* v = &(__nlCurrentContext->variable[i]); __NLVariable* v = &(__nlCurrentContext->variable[i]);
if(!v->locked) { if(!v->locked) {
@ -740,8 +750,10 @@ static void __nlVariablesToVector() {
static void __nlVectorToVariables() { static void __nlVectorToVariables() {
NLuint i; NLuint i;
__nl_assert(__nlCurrentContext->alloc_x); __nl_assert(__nlCurrentContext->alloc_x);
__nl_assert(__nlCurrentContext->alloc_variable); __nl_assert(__nlCurrentContext->alloc_variable);
for(i=0; i<__nlCurrentContext->nb_variables; i++) { for(i=0; i<__nlCurrentContext->nb_variables; i++) {
__NLVariable* v = &(__nlCurrentContext->variable[i]); __NLVariable* v = &(__nlCurrentContext->variable[i]);
if(!v->locked) { if(!v->locked) {
@ -760,8 +772,8 @@ static void __nlBeginSystem() {
__nlTransition(__NL_STATE_INITIAL, __NL_STATE_SYSTEM); __nlTransition(__NL_STATE_INITIAL, __NL_STATE_SYSTEM);
__nlCurrentContext->variable = __NL_NEW_ARRAY( __nlCurrentContext->variable = __NL_NEW_ARRAY(
__NLVariable, __nlCurrentContext->nb_variables __NLVariable, __nlCurrentContext->nb_variables);
);
__nlCurrentContext->alloc_variable = NL_TRUE; __nlCurrentContext->alloc_variable = NL_TRUE;
} }
} }
@ -771,69 +783,93 @@ static void __nlEndSystem() {
} }
static void __nlBeginMatrix() { static void __nlBeginMatrix() {
NLuint i; NLuint i, j;
NLuint n = 0; NLuint n = 0;
NLenum storage = __NL_ROWS; NLenum storage = __NL_ROWS;
__NLContext *context = __nlCurrentContext;
__nlTransition(__NL_STATE_SYSTEM, __NL_STATE_MATRIX); __nlTransition(__NL_STATE_SYSTEM, __NL_STATE_MATRIX);
if (!__nlCurrentContext->solve_again) { if (!context->solve_again) {
for(i=0; i<__nlCurrentContext->nb_variables; i++) { for(i=0; i<context->nb_variables; i++) {
if(!__nlCurrentContext->variable[i].locked) if(context->variable[i].locked) {
__nlCurrentContext->variable[i].index = n++; context->variable[i].index = ~0;
context->variable[i].a = __NL_NEW(__NLRowColumn);
__nlRowColumnConstruct(context->variable[i].a);
}
else else
__nlCurrentContext->variable[i].index = ~0; context->variable[i].index = n++;
} }
__nlCurrentContext->n = n; context->n = n;
/* a least squares problem results in a symmetric matrix */ /* a least squares problem results in a symmetric matrix */
if(__nlCurrentContext->least_squares) if(context->least_squares)
__nlCurrentContext->symmetric = NL_TRUE; context->symmetric = NL_TRUE;
if(__nlCurrentContext->symmetric) if(context->symmetric)
storage = (storage | __NL_SYMMETRIC); storage = (storage | __NL_SYMMETRIC);
/* SuperLU storage does not support symmetric storage */ /* SuperLU storage does not support symmetric storage */
storage = (storage & ~__NL_SYMMETRIC); storage = (storage & ~__NL_SYMMETRIC);
__nlSparseMatrixConstruct(&__nlCurrentContext->M, n, n, storage); __nlSparseMatrixConstruct(&context->M, n, n, storage);
__nlCurrentContext->alloc_M = NL_TRUE; context->alloc_M = NL_TRUE;
__nlCurrentContext->x = __NL_NEW_ARRAY(NLfloat, n); context->b = __NL_NEW_ARRAY(NLfloat, n);
__nlCurrentContext->alloc_x = NL_TRUE; context->alloc_b = NL_TRUE;
__nlCurrentContext->b = __NL_NEW_ARRAY(NLfloat, n); context->x = __NL_NEW_ARRAY(NLfloat, n);
__nlCurrentContext->alloc_b = NL_TRUE; context->alloc_x = NL_TRUE;
} }
else { else {
/* need to recompute b only, A is not constructed anymore */ /* need to recompute b only, A is not constructed anymore */
__NL_CLEAR_ARRAY(NLfloat, __nlCurrentContext->b, __nlCurrentContext->n); __NL_CLEAR_ARRAY(NLfloat, context->b, context->n);
} }
__nlVariablesToVector(); __nlVariablesToVector();
__nlRowColumnConstruct(&__nlCurrentContext->af); __nlRowColumnConstruct(&context->af);
__nlCurrentContext->alloc_af = NL_TRUE; context->alloc_af = NL_TRUE;
__nlRowColumnConstruct(&__nlCurrentContext->al); __nlRowColumnConstruct(&context->al);
__nlCurrentContext->alloc_al = NL_TRUE; context->alloc_al = NL_TRUE;
__nlCurrentContext->current_row = 0; context->current_row = 0;
} }
static void __nlEndMatrix() { static void __nlEndMatrix() {
__NLContext *context = __nlCurrentContext;
__NLVariable *variable;
__NLRowColumn *a;
NLfloat *b;
NLuint i, j;
__nlTransition(__NL_STATE_MATRIX, __NL_STATE_MATRIX_CONSTRUCTED); __nlTransition(__NL_STATE_MATRIX, __NL_STATE_MATRIX_CONSTRUCTED);
__nlRowColumnDestroy(&__nlCurrentContext->af); __nlRowColumnDestroy(&context->af);
__nlCurrentContext->alloc_af = NL_FALSE; context->alloc_af = NL_FALSE;
__nlRowColumnDestroy(&__nlCurrentContext->al); __nlRowColumnDestroy(&context->al);
__nlCurrentContext->alloc_al = NL_FALSE; context->alloc_al = NL_FALSE;
b = context->b;
for(i=0; i<__nlCurrentContext->nb_variables; i++) {
variable = &(context->variable[i]);
if(variable->locked) {
a = variable->a;
for(j=0; j<a->size; j++) {
b[a->coeff[j].index] -= a->coeff[j].value*variable->value;
}
}
}
#if 0 #if 0
if(!__nlCurrentContext->least_squares) { if(!context->least_squares) {
__nl_assert( __nl_assert(
__nlCurrentContext->current_row == context->current_row ==
__nlCurrentContext->n context->n
); );
} }
#endif #endif
@ -895,24 +931,59 @@ static void __nlEndRow() {
void nlMatrixAdd(NLuint row, NLuint col, NLfloat value) void nlMatrixAdd(NLuint row, NLuint col, NLfloat value)
{ {
__NLSparseMatrix* M = &__nlCurrentContext->M; __NLContext *context = __nlCurrentContext;
__nlCheckState(__NL_STATE_MATRIX);
__nl_range_assert(row, 0, __nlCurrentContext->n - 1);
__nl_range_assert(col, 0, __nlCurrentContext->nb_variables - 1);
__nl_assert(!__nlCurrentContext->least_squares);
__nlSparseMatrixAdd(M, row, col, value); __nlCheckState(__NL_STATE_MATRIX);
__nl_assert(!context->least_squares);
if (context->variable[row].locked);
else if (context->variable[col].locked) {
row = context->variable[row].index;
__nlRowColumnAppend(context->variable[col].a, row, value);
}
else {
__NLSparseMatrix* M = &context->M;
row = context->variable[row].index;
col = context->variable[col].index;
__nl_range_assert(row, 0, context->n - 1);
__nl_range_assert(col, 0, context->n - 1);
__nlSparseMatrixAdd(M, row, col, value);
}
} }
void nlRightHandSideAdd(NLuint index, NLfloat value) void nlRightHandSideAdd(NLuint index, NLfloat value)
{ {
NLfloat* b = __nlCurrentContext->b; __NLContext *context = __nlCurrentContext;
NLfloat* b = context->b;
__nlCheckState(__NL_STATE_MATRIX); __nlCheckState(__NL_STATE_MATRIX);
__nl_range_assert(index, 0, __nlCurrentContext->n - 1); __nl_assert(!context->least_squares);
__nl_assert(!__nlCurrentContext->least_squares);
b[index] += value; if(!context->variable[index].locked) {
index = context->variable[index].index;
__nl_range_assert(index, 0, context->n - 1);
b[index] += value;
}
}
void nlRightHandSideSet(NLuint index, NLfloat value)
{
__NLContext *context = __nlCurrentContext;
NLfloat* b = context->b;
__nlCheckState(__NL_STATE_MATRIX);
__nl_assert(!context->least_squares);
if(!context->variable[index].locked) {
index = context->variable[index].index;
__nl_range_assert(index, 0, context->n - 1);
b[index] = value;
}
} }
void nlCoefficient(NLuint index, NLfloat value) { void nlCoefficient(NLuint index, NLfloat value) {
@ -1049,7 +1120,7 @@ static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation)
/* Cleanup */ /* Cleanup */
Destroy_SuperMatrix_Store(&At); Destroy_SuperMatrix_Store(&At);
Destroy_SuperMatrix_Store(&AtP); Destroy_CompCol_Permuted(&AtP);
__NL_DELETE_ARRAY(etree); __NL_DELETE_ARRAY(etree);
__NL_DELETE_ARRAY(xa); __NL_DELETE_ARRAY(xa);