Actual source code: nladic.c
1: #define PETSCMAT_DLL
2: /*
3: ADIC based nonlinear operator object that can be used with FAS
5: This does not really belong in the matrix directories but since it
6: was cloned off of Mat_DAAD I'm leaving it here until I have a better place
8: */
10: #include petscda.h
11: #include petscsys.h
13: #include "adic/ad_utils.h"
16: #include src/dm/da/daimpl.h
18: struct NLF_DAAD {
19: DA da;
20: void *ctx;
21: Vec residual;
22: int newton_its;
23: };
27: /*
28: Solves the one dimensional equation using Newton's method
29: */
32: PetscErrorCode NLFNewton_DAAD(NLF A,DALocalInfo *info,MatStencil *stencil,void *ad_vu,PetscScalar *ad_vustart,int nI,int gI,PetscScalar residual)
33: {
35: PetscInt cnt = A->newton_its;
36: PetscScalar ad_f[2],J,f;
39: ad_vustart[1+2*gI] = 1.0;
41: do {
42: /* compute the function and Jacobian */
43: (*A->da->adicmf_lfi)(info,stencil,ad_vu,ad_f,A->ctx);
44: J = -ad_f[1];
45: f = -ad_f[0] + residual;
46: ad_vustart[2*gI] = ad_vustart[2*gI] - f/J;
47: } while (--cnt > 0 && PetscAbsScalar(f) > 1.e-14);
49: ad_vustart[1+2*gI] = 0.0;
50: return(0);
51: }
54: /*
55: Nonlinear relax on all the equations with an initial guess in xx
56: */
60: PetscErrorCode PETSCMAT_DLLEXPORT NLFRelax_DAAD(NLF A,MatSORType flag,int its,Vec xx)
61: {
63: PetscInt j,gtdof,nI,gI;
64: PetscScalar *avu,*av,*ad_vustart,*residual;
65: Vec localxx;
66: DALocalInfo info;
67: MatStencil stencil;
68: void* *ad_vu;
71: if (its <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
73: DAGetLocalVector(A->da,&localxx);
74: /* get space for derivative object. */
75: DAGetAdicMFArray(A->da,PETSC_TRUE,(void **)&ad_vu,(void**)&ad_vustart,>dof);
76: VecGetArray(A->residual,&residual);
79: /* tell ADIC we will be computing one dimensional Jacobians */
80: PetscADResetIndep();
81: PetscADIncrementTotalGradSize(1);
82: PetscADSetIndepDone();
84: DAGetLocalInfo(A->da,&info);
85: while (its--) {
87: /* get initial solution properly ghosted */
88: DAGlobalToLocalBegin(A->da,xx,INSERT_VALUES,localxx);
89: DAGlobalToLocalEnd(A->da,xx,INSERT_VALUES,localxx);
91: /* copy input vector into derivative object */
92: VecGetArray(localxx,&avu);
93: for (j=0; j<gtdof; j++) {
94: ad_vustart[2*j] = avu[j];
95: ad_vustart[2*j+1] = 0.0;
96: }
97: VecRestoreArray(localxx,&avu);
99: if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
100: nI = 0;
101: for (stencil.k = info.zs; stencil.k<info.zs+info.zm; stencil.k++) {
102: for (stencil.j = info.ys; stencil.j<info.ys+info.ym; stencil.j++) {
103: for (stencil.i = info.xs; stencil.i<info.xs+info.xm; stencil.i++) {
104: for (stencil.c = 0; stencil.c<info.dof; stencil.c++) {
105: gI = stencil.c + (stencil.i - info.gxs)*info.dof + (stencil.j - info.gys)*info.dof*info.gxm + (stencil.k - info.gzs)*info.dof*info.gxm*info.gym;
106: NLFNewton_DAAD(A,&info,&stencil,ad_vu,ad_vustart,nI,gI,residual[nI]);
107: nI++;
108: }
109: }
110: }
111: }
112: }
113: if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
114: nI = info.dof*info.xm*info.ym*info.zm - 1;
115: for (stencil.k = info.zs+info.zm-1; stencil.k>=info.zs; stencil.k--) {
116: for (stencil.j = info.ys+info.ym-1; stencil.j>=info.ys; stencil.j--) {
117: for (stencil.i = info.xs+info.xm-1; stencil.i>=info.xs; stencil.i--) {
118: for (stencil.c = info.dof-1; stencil.c>=0; stencil.c--) {
119: gI = stencil.c + (stencil.i - info.gxs)*info.dof + (stencil.j - info.gys)*info.dof*info.gxm + (stencil.k - info.gzs)*info.dof*info.gxm*info.gym;
120: NLFNewton_DAAD(A,&info,&stencil,ad_vu,ad_vustart,nI,gI,residual[nI]);
121: nI--;
122: }
123: }
124: }
125: }
126: }
128: /* copy solution back into ghosted vector from derivative object */
129: VecGetArray(localxx,&av);
130: for (j=0; j<gtdof; j++) {
131: av[j] = ad_vustart[2*j];
132: }
133: VecRestoreArray(localxx,&av);
134: /* stick relaxed solution back into global solution */
135: DALocalToGlobal(A->da,localxx,INSERT_VALUES,xx);
136: }
139: VecRestoreArray(A->residual,&residual);
140: DARestoreLocalVector(A->da,&localxx);
141: DARestoreAdicMFArray(A->da,PETSC_TRUE,(void **)&ad_vu,(void**)&ad_vustart,>dof);
142: return(0);
143: }
149: PetscErrorCode NLFDestroy_DAAD(NLF A)
150: {
154: DADestroy(A->da);
155: PetscFree(A);
156: return(0);
157: }
163: PetscErrorCode PETSCMAT_DLLEXPORT NLFDAADSetDA_DAAD(NLF A,DA da)
164: {
168: A->da = da;
169: PetscObjectReference((PetscObject)da);
170: return(0);
171: }
177: PetscErrorCode PETSCMAT_DLLEXPORT NLFDAADSetNewtonIterations_DAAD(NLF A,int its)
178: {
180: A->newton_its = its;
181: return(0);
182: }
188: PetscErrorCode PETSCMAT_DLLEXPORT NLFDAADSetResidual_DAAD(NLF A,Vec residual)
189: {
191: A->residual = residual;
192: return(0);
193: }
200: PetscErrorCode PETSCMAT_DLLEXPORT NLFDAADSetCtx_DAAD(NLF A,void *ctx)
201: {
203: A->ctx = ctx;
204: return(0);
205: }
211: PetscErrorCode PETSCMAT_DLLEXPORT NLFCreate_DAAD(NLF *A)
212: {
216: PetscNew(struct NLF_DAAD,A);
217: (*A)->da = 0;
218: (*A)->ctx = 0;
219: (*A)->newton_its = 2;
220: return(0);
221: }