5 #include "../toolkits/toolkits.h"
6 #include "../classes/classes.h"
7 #include "../shared/shared.h"
8 #include "../modules/modules.h"
9 #include "../analyses/analyses.h"
10 #define USEPENALTYMETHOD false
13 void CreateDMatrix(Mat* pD,Mat K){
23 int ncols,ncols2,rstart,rend;
33 MatTranspose(K,MAT_INITIAL_MATRIX,&K_transp);
36 MatDuplicate(K,MAT_SHARE_NONZERO_PATTERN,&D);
39 MatGetOwnershipRange(K,&rstart,&rend);
40 for(
int row=rstart; row<rend; row++){
42 MatGetRow(K ,row,&ncols, (
const int**)&cols, (
const double**)&vals);
43 MatGetRow(K_transp,row,&ncols2,(
const int**)&cols2,(
const double**)&vals2);
45 for(
int j=0; j<ncols; j++) {
47 d =
max(
max(-vals[j],-vals2[j]),0.);
48 MatSetValue(D,row,cols[j],d,INSERT_VALUES);
49 if(cols[j]!=row) diagD -= d;
51 MatSetValue(D,row,row,diagD,INSERT_VALUES);
52 MatRestoreRow(K ,row,&ncols, (
const int**)&cols, (
const double**)&vals);
53 MatRestoreRow(K_transp,row,&ncols2,(
const int**)&cols2,(
const double**)&vals2);
55 MatAssemblyBegin(D,MAT_FINAL_ASSEMBLY);
56 MatAssemblyEnd( D,MAT_FINAL_ASSEMBLY);
70 int dof,ncols,ncols2,rstart,rend;
71 double d,mi,dmax = 0.;
78 MatDuplicate(K,MAT_SHARE_NONZERO_PATTERN,&LHS);
79 MatGetOwnershipRange(K,&rstart,&rend);
80 for(
int row=rstart; row<rend; row++){
81 MatGetRow(K,row,&ncols, (
const int**)&cols, (
const double**)&vals);
82 MatGetRow(D,row,&ncols2,(
const int**)&cols2,(
const double**)&vals2);
84 for(
int j=0; j<ncols; j++) {
86 d = -theta*deltat*(vals[j] + vals2[j]);
88 VecGetValues(Ml,1,(
const int*)&cols[j],&mi);
91 if(fabs(d)>dmax) dmax = fabs(d);
92 MatSetValue(LHS,row,cols[j],d,INSERT_VALUES);
94 MatRestoreRow(K,row,&ncols, (
const int**)&cols, (
const double**)&vals);
95 MatRestoreRow(D,row,&ncols2,(
const int**)&cols2,(
const double**)&vals2);
97 MatAssemblyBegin(LHS,MAT_FINAL_ASSEMBLY);
98 MatAssemblyEnd( LHS,MAT_FINAL_ASSEMBLY);
115 MatSetValue(LHS,dof,dof,dmax,INSERT_VALUES);
122 int* rows = xNew<int>(numrows);
123 IssmDouble* rows_spc = xNew<IssmDouble>(numrows);
135 MatZeroRows(LHS,numrows,rows,1.,NULL,NULL);
137 xDelete<IssmDouble>(rows_spc);
139 MatAssemblyBegin(LHS,MAT_FINAL_ASSEMBLY);
140 MatAssemblyEnd( LHS,MAT_FINAL_ASSEMBLY);
146 void CreateRHS(Vec* pRHS,Mat K,Mat D,Vec Ml,Vec p,Vec u,
IssmDouble theta,
IssmDouble deltat,
IssmDouble dmax,
FemModel*
femmodel,
int configuration_type){
165 VecDuplicate(u,&RHS);
170 VecPointwiseMult(RHS,Ml,u);
171 VecAXPBYPCZ(RHS,(1-theta)*deltat,(1-theta)*deltat,1,Ku,Du);
172 VecAXPBY(RHS,deltat,1,p);
176 VecAssemblyBegin(RHS);
177 VecAssemblyEnd( RHS);
187 VecSetValues(RHS,1,&dof,(
const double*)&d,INSERT_VALUES);
194 int* rows = xNew<int>(numrows);
195 IssmDouble* rows_spc = xNew<IssmDouble>(numrows);
202 rows_spc[numrows] = d;
206 VecSetValues(RHS,numrows,rows,rows_spc,INSERT_VALUES);
208 xDelete<IssmDouble>(rows_spc);
210 VecAssemblyBegin(RHS);
211 VecAssemblyEnd( RHS);
217 void RichardsonUdot(Vec* pudot,Vec u,Vec Ml,Mat K,Mat Mc){
230 VecDuplicate(u,&udot);
231 VecDuplicate(u,&temp1);
232 VecDuplicate(u,&temp2);
235 VecZeroEntries(udot);
238 for(
int i=0;i<5;i++){
239 MatMult(Mc,udot,temp1);
240 MatMult(K, u, temp2);
241 VecAXPBY(temp2,-1.,1.,temp1);
242 VecPointwiseDivide(temp1,temp2,Ml);
243 VecAXPBY(udot,1.,1.,temp1);
252 void CreateRis(
IssmDouble** pRi_plus_serial,
IssmDouble** pRi_minus_serial,Mat Mc,Mat D,
IssmDouble* ml_serial,Vec uvec,
IssmDouble* u,
IssmDouble* udot,
IssmDouble* ulmin,
IssmDouble* ulmax,
IssmDouble deltat){
257 int ncols,ncols2,rstart,rend;
262 double *vals2 = NULL;
265 VecDuplicate(uvec,&Ri_plus);
266 VecDuplicate(uvec,&Ri_minus);
271 VecGetSize(uvec,&ncols);
272 for(
int i=1;i<ncols;i++)
if(ulmin[i]<uLmin_global) uLmin_global = ulmin[i];
273 for(
int i=1;i<ncols;i++)
if(ulmax[i]>uLmax_global) uLmax_global = ulmax[i];
277 MatGetOwnershipRange(D,&rstart,&rend);
278 for(
int row=rstart; row<rend; row++){
280 double Pi_minus = 0.;
281 MatGetRow(Mc,row,&ncols, (
const int**)&cols, (
const double**)&vals);
282 MatGetRow(D ,row,&ncols2,(
const int**)&cols2,(
const double**)&vals2);
284 for(
int j=0; j<ncols; j++) {
286 d = vals[j]*(udot[row] - udot[cols[j]]) + vals2[j]*(u[row] - u[cols[j]]);
300 double Qi_plus = ml_serial[row]/deltat*(ulmax[row] - u[row]);
301 double Qi_minus = ml_serial[row]/deltat*(ulmin[row] - u[row]);
307 if(Pi_plus!=0.) d =
min(1.,Qi_plus/Pi_plus);
308 VecSetValue(Ri_plus,row,d,INSERT_VALUES);
310 if(Pi_minus!=0.) d =
min(1.,Qi_minus/Pi_minus);
311 VecSetValue(Ri_minus,row,d,INSERT_VALUES);
313 MatRestoreRow(Mc,row,&ncols, (
const int**)&cols, (
const double**)&vals);
314 MatRestoreRow(D ,row,&ncols2,(
const int**)&cols2,(
const double**)&vals2);
316 VecAssemblyBegin(Ri_plus);
317 VecAssemblyEnd( Ri_plus);
318 VecAssemblyBegin(Ri_minus);
319 VecAssemblyEnd( Ri_minus);
330 *pRi_plus_serial = Ri_plus_serial;
331 *pRi_minus_serial = Ri_minus_serial;
337 int ncols,ncols2,rstart,rend;
342 double *vals2 = NULL;
345 VecDuplicate(uvec,&Fbar);
346 MatGetOwnershipRange(D,&rstart,&rend);
347 for(
int row=rstart; row<rend; row++){
348 MatGetRow(Mc,row,&ncols, (
const int**)&cols, (
const double**)&vals);
349 MatGetRow(D ,row,&ncols2,(
const int**)&cols2,(
const double**)&vals2);
352 for(
int j=0; j<ncols; j++) {
354 if(row==cols[j])
continue;
355 f_ij = vals[j]*(udot[row] - udot[cols[j]]) + vals2[j]*(u[row] - u[cols[j]]);
357 d +=
min(Ri_plus[row],Ri_minus[cols[j]]) * f_ij;
360 d +=
min(Ri_minus[row],Ri_plus[cols[j]]) * f_ij;
363 VecSetValue(Fbar,row,d,INSERT_VALUES);
364 MatRestoreRow(Mc,row,&ncols, (
const int**)&cols, (
const double**)&vals);
365 MatRestoreRow(D ,row,&ncols2,(
const int**)&cols2,(
const double**)&vals2);
367 VecAssemblyBegin(Fbar);
368 VecAssemblyEnd( Fbar);
373 void UpdateSolution(Vec u,Vec udot,Vec Ml,Vec Fbar,
IssmDouble deltat){
379 VecDuplicate(u,&temp1);
380 VecPointwiseDivide(temp1,Fbar,Ml);
381 VecAXPBY(udot,1.,1.,temp1);
382 VecAXPY(u,deltat,temp1);
392 int configuration_type,analysis_type;
409 switch(analysis_type){
421 default:
_error_(
"analysis type " <<
EnumToStringx(analysis_type) <<
" not supported for FCT\n");
434 Mat K_petsc = K->pmatrix->matrix;
435 Mat Mc_petsc = Mc->pmatrix->matrix;
436 Vec p_petsc = p->pvector->vector;
445 VecDuplicate(uf->pvector->vector,&Ml_petsc);
446 MatGetRowSum(Mc_petsc,Ml_petsc);
449 CreateDMatrix(&D_petsc,K_petsc);
452 CreateLHS(&LHS,&dmax,K_petsc,D_petsc,Ml_petsc,theta,deltat,
femmodel,configuration_type);
455 CreateRHS(&RHS,K_petsc,D_petsc,Ml_petsc,p_petsc,uf->pvector->vector,theta,deltat,dmax,
femmodel,configuration_type);
467 RichardsonUdot(&udot,u,Ml_petsc,K_petsc,Mc_petsc);
485 CreateRis(&Ri_plus_serial,&Ri_minus_serial,Mc_petsc,D_petsc,ml_serial,u,u_serial,udot_serial,ulmin,ulmax,deltat);
486 CreateFbar(&Fbar,Ri_plus_serial,Ri_minus_serial,Mc_petsc,D_petsc,udot_serial,u_serial,u);
487 xDelete<IssmDouble>(Ri_plus_serial);
488 xDelete<IssmDouble>(Ri_minus_serial);
489 xDelete<IssmDouble>(ulmin);
490 xDelete<IssmDouble>(ulmax);
495 xDelete<IssmDouble>(udot_serial);
496 xDelete<IssmDouble>(u_serial);
497 xDelete<IssmDouble>(ml_serial);
500 UpdateSolution(u,udot,Ml_petsc,Fbar,deltat);
512 _error_(
"PETSc needs to be installed");