9 #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
12 #include "../../shared/Numerics/types.h"
13 #include "../../shared/MemOps/MemOps.h"
14 #include "../../shared/Exceptions/exceptions.h"
15 #include "../../shared/io/Comm/IssmComm.h"
16 #include "../../classes/Params/GenericParam.h"
17 #include "../../classes/Params/Parameters.h"
18 #include "../mpi/issmmpi.h"
19 #include "../adolc/adolcincludes.h"
20 #include "../codipack/codipackincludes.h"
21 #include "../issm/SparseRow.h"
30 theMumpsStruc.a = NULL;
31 theMumpsStruc.jcn = NULL;
32 theMumpsStruc.irn = NULL;
33 theMumpsStruc.par = 1;
34 theMumpsStruc.sym = 0;
38 theMumpsStruc.job = -1;
39 dmumps_c(&theMumpsStruc);
45 theMumpsStruc.icntl[1-1] = 0;
46 theMumpsStruc.icntl[2-1] = 0;
47 theMumpsStruc.icntl[3-1] = 0;
48 theMumpsStruc.icntl[4-1] = 0;
49 theMumpsStruc.icntl[5-1] = 0;
50 theMumpsStruc.icntl[18-1] = 3;
52 theMumpsStruc.icntl[20-1] = 0;
53 theMumpsStruc.icntl[21-1] = 0;
54 theMumpsStruc.icntl[30-1] = 0;
60 theMumpsStruc.job = 1;
61 dmumps_c(&theMumpsStruc);
66 theMumpsStruc.job = 2;
67 dmumps_c(&theMumpsStruc);
72 theMumpsStruc.job = 3;
73 dmumps_c(&theMumpsStruc);
78 theMumpsStruc.job = -2;
79 dmumps_c(&theMumpsStruc);
84 DMUMPS_STRUC_C theMumpsStruc;
91 theMumpsStruc.nz_loc=local_nnz;
92 theMumpsStruc.irn_loc=irn_loc;
93 theMumpsStruc.jcn_loc=jcn_loc;
94 theMumpsStruc.a_loc=a_loc;
95 theMumpsStruc.rhs=rhs;
119 void MpiDenseMumpsSolve(
IssmDouble* uf,
int uf_M,
int uf_m,
IssmDouble* Kff,
int Kff_M,
int Kff_N,
int Kff_m,
IssmDouble* pf,
int pf_M,
int pf_m,
Parameters* parameters){
133 int *recvcounts = NULL;
141 if (Kff_M!=Kff_N)
_error_(
"stiffness matrix Kff should be square");
142 if (uf_M!=Kff_M || uf_M!=pf_M)
_error_(
"solution vector should be the same size as stiffness matrix Kff and load vector pf");
143 if (uf_m!=Kff_m || uf_m!=pf_m)
_error_(
"solution vector should be locally the same size as stiffness matrix Kff and load vector pf");
148 for(i=0;i<Kff_m;i++){
149 for(j=0;j<Kff_N;j++){
150 if (Kff[i*Kff_N+j]!=0)local_nnz++;
159 irn_loc=xNew<int>(local_nnz);
160 jcn_loc=xNew<int>(local_nnz);
161 a_loc=xNew<IssmDouble>(local_nnz);
167 for(i=0;i<Kff_m;i++){
168 for(j=0;j<Kff_N;j++){
169 if (Kff[i*Kff_N+j]!=0){
170 irn_loc[count]=lower_row+i+1;
172 a_loc[count]=Kff[i*Kff_N+j];
181 rhs=xNew<IssmDouble>(pf_M,
"t");
183 rhs=xNew<IssmDouble>(pf_M);
186 recvcounts=xNew<int>(num_procs);
187 displs=xNew<int>(num_procs);
198 MumpsSolve(Kff_M,nnz,local_nnz,irn_loc,jcn_loc,a_loc,rhs,parameters);
204 xDelete<int>(irn_loc);
205 xDelete<int>(jcn_loc);
206 xDelete<IssmDouble>(a_loc);
207 xDelete<IssmDouble>(rhs);
208 xDelete<int>(recvcounts);
209 xDelete<int>(displs);
211 void MpiSparseMumpsSolve(
IssmDouble* uf,
int uf_M,
int uf_m,
SparseRow<IssmDouble>** Kff,
int Kff_M,
int Kff_N,
int Kff_m,
IssmDouble* pf,
int pf_M,
int pf_m,
Parameters* parameters){
225 int *recvcounts = NULL;
233 if(Kff_M!=Kff_N)
_error_(
"stiffness matrix Kff should be square");
234 if(uf_M!=Kff_M || uf_M!=pf_M)
_error_(
"solution vector should be the same size as stiffness matrix Kff and load vector pf");
235 if(uf_m!=Kff_m || uf_m!=pf_m)
_error_(
"solution vector should be locally the same size as stiffness matrix Kff and load vector pf");
240 for(i=0;i<Kff_m;i++){
241 local_nnz+=Kff[i]->
Nnz();
249 irn_loc=xNew<int>(local_nnz);
250 jcn_loc=xNew<int>(local_nnz);
251 a_loc=xNew<IssmDouble>(local_nnz);
257 for(i=0;i<Kff_m;i++){
258 Kff[i]->
SetIrnJcnA(irn_loc,jcn_loc,a_loc,lower_row+i+1,count);
259 count+=Kff[i]->
Nnz();
265 rhs=xNew<IssmDouble>(pf_M,
"t");
267 rhs=xNew<IssmDouble>(pf_M);
270 recvcounts=xNew<int>(num_procs);
271 displs=xNew<int>(num_procs);
282 MumpsSolve(Kff_M,nnz,local_nnz,irn_loc,jcn_loc,a_loc,rhs,parameters);
288 xDelete<int>(irn_loc);
289 xDelete<int>(jcn_loc);
290 xDelete<IssmDouble>(a_loc);
291 xDelete<IssmDouble>(rhs);
292 xDelete<int>(recvcounts);
293 xDelete<int>(displs);
296 void SeqDenseMumpsSolve(
IssmDouble* uf,
int uf_M,
int uf_m,
IssmDouble* Kff,
int Kff_M,
int Kff_N,
int Kff_m,
IssmDouble* pf,
int pf_M,
int pf_m,
Parameters* parameters){
305 if (Kff_M!=Kff_N)
_error_(
"stiffness matrix Kff should be square");
306 if (Kff_M!=Kff_m)
_error_(
"stiffness matrix Kff is not serial");
307 if (uf_M!=Kff_M || uf_M!=pf_M)
_error_(
"solution vector should be the same size as stiffness matrix Kff and load vector pf");
308 if (uf_m!=Kff_m || uf_m!=pf_m)
_error_(
"solution vector should be locally the same size as stiffness matrix Kff and load vector pf");
313 for(
int i=0;i<Kff_M;i++){
314 for(
int j=0;j<Kff_N;j++){
315 if(Kff[i*Kff_N+j]!=0)nnz++;
321 irn_loc = xNew<int>(nnz);
322 jcn_loc = xNew<int>(nnz);
323 a_loc = xNew<IssmDouble>(nnz);
328 for(
int i=0;i<Kff_M;i++){
329 for(
int j=0;j<Kff_N;j++){
330 if(Kff[i*Kff_N+j]!=0){
331 irn_loc[count] = i+1;
332 jcn_loc[count] = j+1;
333 a_loc[count] = Kff[i*Kff_N+j];
343 rhs=xNew<IssmDouble>(pf_M,
"t");
345 rhs=xNew<IssmDouble>(pf_M);
347 xMemCpy<IssmDouble>(rhs,pf,Kff_M);
349 MumpsSolve(Kff_M,nnz,nnz,irn_loc,jcn_loc,a_loc,rhs,parameters);
352 xMemCpy<IssmDouble>(uf,rhs,Kff_M);
355 xDelete<int>(irn_loc);
356 xDelete<int>(jcn_loc);
357 xDelete<IssmDouble>(a_loc);
358 xDelete<IssmDouble>(rhs);
366 int local_nnz=iArr[2];
367 int *local_irn=xNew<int>(local_nnz);
368 int *local_jcn=xNew<int>(local_nnz);
370 for (
int i=0;i<local_nnz;++i) {
371 local_irn[i]=iArr[3+i];
372 local_jcn[i]=iArr[3+local_nnz+i];
376 for (
int i=0;i<n;++i) {
377 rhs_sol[i]=dp_x[local_nnz+i];
379 MumpsSolve(n,nnz,local_nnz,local_irn,local_jcn,A,rhs_sol);
380 for (
int i=0;i<n;++i) {
390 int packedDimsSparseArrLength=1+1+1+local_nnz+local_nnz;
391 int *packedDimsSparseArr=xNew<int>(packedDimsSparseArrLength);
392 packedDimsSparseArr[0]=n;
393 packedDimsSparseArr[1]=nnz;
394 packedDimsSparseArr[2]=local_nnz;
395 for (
int i=0;i<local_nnz;++i) {
396 packedDimsSparseArr[3+i]=irn_loc[i];
397 packedDimsSparseArr[3+local_nnz+i]=jcn_loc[i];
402 IssmDouble *pack_A_rhs=xNew<IssmDouble>(local_nnz+n,
"t");
404 IssmDouble *pack_A_rhs=xNew<IssmDouble>(local_nnz+n);
407 for (
int i=0;i<local_nnz;++i) {
408 pack_A_rhs[i]=a_loc[i];
410 for (
int i=0;i<n;++i) {
411 pack_A_rhs[local_nnz+i]=rhs[i];
422 packedDimsSparseArrLength, packedDimsSparseArr,
423 local_nnz+n, pack_A_rhs,
425 for (
int i=0;i<n;++i) {
436 int local_nnz=iArr[2];
437 int *local_irn=xNew<int>(local_nnz);
438 int *local_jcn=xNew<int>(local_nnz);
440 for (
int i=0;i<local_nnz;++i) {
441 local_irn[i]=iArr[3+i];
442 local_jcn[i]=iArr[3+local_nnz+i];
446 for (
int i=0;i<n;++i) {
449 DMUMPS_STRUC_C theMumpsStruc;
453 theMumpsStruc.nz=nnz;
454 theMumpsStruc.nz_loc=local_nnz;
455 theMumpsStruc.irn_loc=local_irn;
456 theMumpsStruc.jcn_loc=local_jcn;
457 theMumpsStruc.a_loc=a_loc;
458 theMumpsStruc.rhs=rhs_sol;
459 theMumpsStruc.nrhs=1;
460 theMumpsStruc.lrhs=1;
461 theMumpsStruc.icntl[9-1] = 0;
467 for (
int i=0;i<n;++i) {
468 dp_Z[local_nnz+i]+=rhs_sol[i];
475 for (
int i=0;i<local_nnz;++i) {
476 dp_Z[i]-=rhs_sol[iArr[3+i]-1]*dp_y[iArr[3+local_nnz+i]-1];
486 #ifdef _HAVE_CODIPACK_
487 void MumpsSolve_codi_b(
void* tape_in,
void* data_in,
void* ra) {
490 codi::DataStore* data = (codi::DataStore*)data_in;
492 IssmDouble::TapeType& tape = IssmDouble::getGlobalTape();
495 IssmDouble::Real* valueATrans;
496 IssmDouble::GradientData* indexATrans;
499 IssmDouble::GradientData* indexB;
500 IssmDouble::Real* valueX;
501 IssmDouble::GradientData* indexX;
507 data->getData(valueATrans);
508 data->getData(indexATrans);
509 data->getData(irnATrans);
510 data->getData(jcnATrans);
511 data->getData(indexB);
512 data->getData(valueX);
513 data->getData(indexX);
516 data->getData(local_nnz);
517 data->getData(parameters);
520 IssmDouble::GradientValue* adjX = xNew<IssmDouble::GradientValue>(n);
521 getVectorAdjoint(tape, indexX, adjX, n);
523 MumpsSolve(n, nnz, local_nnz, irnATrans, jcnATrans, valueATrans, adjX, parameters);
526 updateVectorAdjoint(tape, indexB, adjX, n);
533 for(
int i=0; i<local_nnz; ++i) {
536 updateAdjoint(tape, indexATrans[i], -adjX[jcnATrans[i]-1]*valueX[irnATrans[i]-1]);
542 void MumpsSolve_codi_delete(
void* tape_in,
void* data_in) {
545 codi::DataStore* data = (codi::DataStore*)data_in;
547 IssmDouble::Real* valueATrans;
548 IssmDouble::GradientData* indexATrans;
551 IssmDouble::GradientData* indexB;
552 IssmDouble::Real* valueX;
553 IssmDouble::GradientData* indexX;
559 data->getData(valueATrans);
560 data->getData(indexATrans);
561 data->getData(irnATrans);
562 data->getData(jcnATrans);
563 data->getData(indexB);
564 data->getData(valueX);
565 data->getData(indexX);
568 data->getData(local_nnz);
569 data->getData(parameters);
581 IssmDouble::TapeType& tape = IssmDouble::getGlobalTape();
582 codi::DataStore* dataHandler = NULL;
584 if(tape.isActive()) {
585 dataHandler =
new codi::DataStore();
588 IssmDouble::Real* valueATrans = xNew<IssmDouble::Real>(local_nnz);
589 IssmDouble::GradientData* indexATrans = xNew<IssmDouble::GradientData>(local_nnz);
590 int* irnATrans = xNew<int>(local_nnz);
591 int* jcnATrans = xNew<int>(local_nnz);
594 for (
int i=0; i<local_nnz; ++i) {
595 getPrimalAndGradData(a_loc[i], valueATrans[i], indexATrans[i]);
596 irnATrans[i]=jcn_loc[i];
597 jcnATrans[i]=irn_loc[i];
601 IssmDouble::GradientData* indexB = xNew<IssmDouble::GradientData>(n);
602 getVectorGradData(rhs, indexB, n);
604 dataHandler->addData(valueATrans);
605 dataHandler->addData(indexATrans);
606 dataHandler->addData(irnATrans);
607 dataHandler->addData(jcnATrans);
608 dataHandler->addData(indexB);
612 IssmDouble::Real* valueA = xNew<IssmDouble::Real>(local_nnz);
613 IssmDouble::Real* valueB = xNew<IssmDouble::Real>(n);
615 getVectorPrimal(a_loc, valueA, local_nnz);
616 getVectorPrimal(rhs, valueB, n);
618 MumpsSolve(n, nnz, local_nnz, irn_loc, jcn_loc, valueA, valueB, parameters);
622 setVectorPrimal(rhs, valueB, n);
624 if(tape.isActive()) {
626 IssmDouble::GradientData* indexX = xNew<IssmDouble::GradientData>(n);
627 registerVector(rhs, indexX, n);
629 dataHandler->addData(valueB);
630 dataHandler->addData(indexX);
633 dataHandler->addData(n);
634 dataHandler->addData(nnz);
635 dataHandler->addData(local_nnz);
636 dataHandler->addData(parameters);
639 tape.pushExternalFunctionHandle(&MumpsSolve_codi_b,(
void*)dataHandler, &MumpsSolve_codi_delete);