9 #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
12 #include "../../shared/shared.h"
13 #include "../../classes/Params/GenericParam.h"
14 #include "../../classes/Params/Parameters.h"
15 #include "../adolc/adolcincludes.h"
16 #include "../codipack/codipackincludes.h"
20 #include <gsl/gsl_linalg.h>
39 if(Kff_N!=pf_M)
_error_(
"Right hand side vector of size " << pf_M <<
", when matrix is of size " << Kff_M <<
"-" << Kff_N <<
" !");
40 if(Kff_M!=Kff_N)
_error_(
"Stiffness matrix should be square!");
55 gsl_permutation *p = NULL;
59 double* Acopy = xNew<double>(n*n);
63 a = gsl_matrix_view_array (Acopy,n,n);
64 b = gsl_vector_view_array (B,n);
65 x = gsl_vector_view_array (X,n);
68 p = gsl_permutation_alloc (n);
69 gsl_linalg_LU_decomp (&a.matrix, p, &s);
70 gsl_linalg_LU_solve (&a.matrix, p, &b.vector, &x.vector);
74 gsl_permutation_free(p);
89 double* Acopy = xNew<double>(m*m);
92 gsl_matrix_view gsl_A = gsl_matrix_view_array (Acopy,m,m);
93 gsl_vector_view gsl_b = gsl_vector_view_array (inVal+m*m,m);
94 gsl_permutation *perm_p = gsl_permutation_alloc (m);
97 gsl_linalg_LU_decomp (&gsl_A.matrix, perm_p, &signPerm);
98 gsl_vector *gsl_x_p = gsl_vector_alloc (m);
100 gsl_linalg_LU_solve (&gsl_A.matrix, perm_p, &gsl_b.vector, gsl_x_p);
102 xMemCpy(outVal,gsl_vector_ptr(gsl_x_p,0),m);
103 gsl_vector_free(gsl_x_p);
107 double* r=xNew<double>(m);
108 for (
int i=0; i<m; i++) {
110 for (
int j=0;j<m; j++) {
111 r[i]-=inDeriv[i*m+j]*outVal[j];
114 gsl_vector_view gsl_r=gsl_vector_view_array(r,m);
115 gsl_vector *gsl_dx_p = gsl_vector_alloc(m);
116 gsl_linalg_LU_solve (&gsl_A.matrix, perm_p, &gsl_r.vector, gsl_dx_p);
117 xMemCpy(outDeriv,gsl_vector_ptr(gsl_dx_p,0),m);
118 gsl_vector_free(gsl_dx_p);
120 gsl_permutation_free(perm_p);
128 double* Acopy = xNew<double>(m*m);
131 gsl_matrix_view gsl_A = gsl_matrix_view_array (Acopy,m,m);
132 gsl_vector_view gsl_b = gsl_vector_view_array (inVal+m*m,m);
133 gsl_permutation *perm_p = gsl_permutation_alloc (m);
136 gsl_linalg_LU_decomp (&gsl_A.matrix, perm_p, &signPerm);
137 gsl_vector *gsl_x_p = gsl_vector_alloc (m);
139 gsl_linalg_LU_solve (&gsl_A.matrix, perm_p, &gsl_b.vector, gsl_x_p);
141 xMemCpy(outVal,gsl_vector_ptr(gsl_x_p,0),m);
142 gsl_vector_free(gsl_x_p);
144 double* r=xNew<double>(m);
145 gsl_vector *gsl_dx_p = gsl_vector_alloc(m);
146 for (
int dir=0;dir<directionCount;++dir) {
148 for (
int i=0; i<m; i++) {
149 r[i]=inDeriv[m*m+i][dir];
150 for (
int j=0;j<m; j++) {
151 r[i]-=inDeriv[i*m+j][dir]*outVal[j];
154 gsl_vector_view gsl_r=gsl_vector_view_array(r,m);
155 gsl_linalg_LU_solve (&gsl_A.matrix, perm_p, &gsl_r.vector, gsl_dx_p);
157 xMemCpy(r,gsl_vector_ptr(gsl_dx_p,0),m);
158 for (
int i=0; i<m; i++) {
159 outDeriv[i][dir]=r[i];
162 gsl_vector_free(gsl_dx_p);
164 gsl_permutation_free(perm_p);
170 int EDF_fos_reverse_for_solverx(
int m,
double *dp_U,
int n,
double *dp_Z,
double* dp_x,
double* dp_y) {
172 double* transposed=xNew<double>(m*m);
173 for (
int i=0; i<m; ++i)
for (
int j=0; j<m; ++j) transposed[j*m+i]=dp_x[i*m+j];
174 gsl_matrix_view aTransposed = gsl_matrix_view_array (transposed,m,m);
176 gsl_vector_view x_bar=gsl_vector_view_array(dp_U,m);
178 gsl_vector_view b_bar=gsl_vector_view_array(dp_Z+m*m,m);
179 gsl_permutation *perm_p = gsl_permutation_alloc (m);
181 gsl_linalg_LU_decomp (&aTransposed.matrix, perm_p, &permSign);
182 gsl_linalg_LU_solve (&aTransposed.matrix, perm_p, &x_bar.vector, &b_bar.vector);
184 for (
int i=0; i<m; ++i)
for (
int j=0; j<m; ++j) dp_Z[i*m+j]-=dp_Z[m*m+i]*dp_y[j];
185 gsl_permutation_free(perm_p);
190 int EDF_fov_reverse_for_solverx(
int m,
int p,
double **dpp_U,
int n,
double **dpp_Z,
double* dp_x,
double* dp_y) {
192 double* transposed=xNew<double>(m*m);
193 for (
int i=0; i<m; ++i)
for (
int j=0; j<m; ++j) transposed[j*m+i]=dp_x[i*m+j];
194 gsl_matrix_view aTransposed = gsl_matrix_view_array (transposed,m,m);
195 gsl_permutation *perm_p = gsl_permutation_alloc (m);
197 gsl_linalg_LU_decomp (&aTransposed.matrix, perm_p, &permSign);
198 for (
int weightsRowIndex=0;weightsRowIndex<p;++weightsRowIndex) {
200 gsl_vector_view x_bar=gsl_vector_view_array(dpp_U[weightsRowIndex],m);
202 gsl_vector_view b_bar=gsl_vector_view_array(dpp_Z[weightsRowIndex]+m*m,m);
203 gsl_linalg_LU_solve (&aTransposed.matrix, perm_p, &x_bar.vector, &b_bar.vector);
205 for (
int i=0; i<m; ++i)
for (
int j=0; j<m; ++j) dpp_Z[weightsRowIndex][i*m+j]-=dpp_Z[weightsRowIndex][m*m+i]*dp_y[j];
207 gsl_permutation_free(perm_p);
216 if(Kff_N!=pf_M)
_error_(
"Right hand side vector of size " << pf_M <<
", when matrix is of size " << Kff_M <<
"-" << Kff_N <<
" !");
217 if(Kff_M!=Kff_N)
_error_(
"Stiffness matrix should be square!");
238 IssmDouble* adoubleEDFin=xNew<IssmDouble>(n*(n+1),
"t");
240 IssmDouble* adoubleEDFin=xNew<IssmDouble>(n*(n+1));
243 for(
int i=0; i<n*n;i++)adoubleEDFin[i] =A[i];
244 for(
int i=0; i<n; i++)adoubleEDFin[i+n*n]=B[i];
247 n*(n+1), adoubleEDFin,
255 #ifdef _HAVE_CODIPACK_
256 void SolverxSeq_codi_b(
void* tape_in,
void* data_in,
void* ra) {
259 codi::DataStore* data = (codi::DataStore*)data_in;
261 IssmDouble::TapeType& tape = IssmDouble::getGlobalTape();
263 IssmDouble::Real* valueATrans;
264 IssmDouble::GradientData* indexATrans;
265 IssmDouble::GradientData* indexB;
266 IssmDouble::Real* valueX;
267 IssmDouble::GradientData* indexX;
270 data->getData(valueATrans);
271 data->getData(indexATrans);
272 data->getData(indexB);
273 data->getData(valueX);
274 data->getData(indexX);
279 IssmDouble::GradientValue* adjX = xNew<IssmDouble::GradientValue>(n);
280 getVectorAdjoint(tape, indexX, adjX, n);
282 IssmDouble::GradientValue* sol = xNew<IssmDouble::GradientValue>(n);
285 updateVectorAdjoint(tape, indexB, sol, n);
286 for(
int i=0; i<n; ++i) {
287 for (
int j=0; j<n; ++j) {
289 updateAdjoint(tape, indexATrans[i*n+j], -sol[j]*valueX[i]);
297 void SolverxSeq_codi_delete(
void* tape_in,
void* data_in) {
300 codi::DataStore* data = (codi::DataStore*)data_in;
302 IssmDouble::Real* valueATrans;
303 IssmDouble::GradientData* indexATrans;
304 IssmDouble::GradientData* indexB;
305 IssmDouble::Real* valueX;
306 IssmDouble::GradientData* indexX;
309 data->getData(valueATrans);
310 data->getData(indexATrans);
311 data->getData(indexB);
312 data->getData(valueX);
313 data->getData(indexX);
324 IssmDouble::TapeType& tape = IssmDouble::getGlobalTape();
325 codi::DataStore* dataHandler = NULL;
327 if(tape.isActive()) {
328 dataHandler =
new codi::DataStore();
331 IssmDouble::Real* valueATrans = xNew<IssmDouble::Real>(n*n);
332 IssmDouble::GradientData* indexATrans = xNew<IssmDouble::GradientData>(n*n);
335 for (
int i=0; i<n; ++i) {
336 for (
int j=0; j<n; ++j) {
337 getPrimalAndGradData(A[i*n+j], valueATrans[j*n+i], indexATrans[j*n+i]);
342 IssmDouble::GradientData* indexB = xNew<IssmDouble::GradientData>(n);
343 getVectorGradData(B, indexB, n);
345 dataHandler->addData(valueATrans);
346 dataHandler->addData(indexATrans);
347 dataHandler->addData(indexB);
351 IssmDouble::Real* valueA = xNew<IssmDouble::Real>(n*n);
352 IssmDouble::Real* valueB = xNew<IssmDouble::Real>(n);
354 getVectorPrimal(A, valueA, n*n);
355 getVectorPrimal(B, valueB, n);
358 IssmDouble::Real* valueX = xNew<IssmDouble::Real>(n);
362 setVectorPrimal(X, valueX, n);
364 if(tape.isActive()) {
366 IssmDouble::GradientData* indexX = xNew<IssmDouble::GradientData>(n);
367 registerVector(X, indexX, n);
369 dataHandler->addData(valueX);
370 dataHandler->addData(indexX);
373 dataHandler->addData(n);
375 tape.pushExternalFunctionHandle(&SolverxSeq_codi_b, dataHandler, &SolverxSeq_codi_delete);
389 if(Kff_N!=pf_M)
_error_(
"Right hand side vector of size " << pf_M <<
", when matrix is of size " << Kff_M <<
"-" << Kff_N <<
" !");
390 if(Kff_M!=Kff_N)
_error_(
"Stiffness matrix should be square!");