forked from bartvdbraak/blender
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:
parent
373f91c8b1
commit
eb8ee6f568
4
intern/opennl/extern/ONL_opennl.h
vendored
4
intern/opennl/extern/ONL_opennl.h
vendored
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user