Actual source code: nladic.c
1: /*$Id: matadic.c,v 1.13 2001/08/07 03:03:06 balay Exp $*/
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
12: EXTERN_C_BEGIN
13: #include "adic/ad_utils.h"
14: EXTERN_C_END
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: int NLFNewton_DAAD(NLF A,DALocalInfo *info,MatStencil *stencil,void *ad_vu,PetscScalar *ad_vustart,int nI,int gI,PetscScalar residual)
33: {
34: int ierr,cnt = A->newton_its;
35: PetscScalar ad_f[2],J,f;
38: ad_vustart[1+2*gI] = 1.0;
40: do {
41: /* compute the function and Jacobian */
42: (*A->da->adicmf_lfi)(info,stencil,ad_vu,ad_f,A->ctx);
43: J = -ad_f[1];
44: f = -ad_f[0] + residual;
45: ad_vustart[2*gI] = ad_vustart[2*gI] - f/J;
46: /* printf("nI %d f %g J %g\n",nI,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: */
57: EXTERN_C_BEGIN
60: int NLFRelax_DAAD(NLF A,MatSORType flag,int its,Vec xx)
61: {
62: int ierr,j,gtdof,nI,gI;
63: PetscScalar *avu,*av,*ad_vustart,*residual;
64: Vec localxx;
65: DALocalInfo info;
66: MatStencil stencil;
67: void* *ad_vu;
70: if (its <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %d positive",its);
72: DAGetLocalVector(A->da,&localxx);
73: /* get space for derivative object. */
74: DAGetAdicMFArray(A->da,PETSC_TRUE,(void **)&ad_vu,(void**)&ad_vustart,>dof);
75: VecGetArray(A->residual,&residual);
78: /* tell ADIC we will be computing one dimensional Jacobians */
79: PetscADResetIndep();
80: PetscADIncrementTotalGradSize(1);
81: PetscADSetIndepDone();
83: DAGetLocalInfo(A->da,&info);
84: while (its--) {
86: /* get initial solution properly ghosted */
87: DAGlobalToLocalBegin(A->da,xx,INSERT_VALUES,localxx);
88: DAGlobalToLocalEnd(A->da,xx,INSERT_VALUES,localxx);
90: /* copy input vector into derivative object */
91: VecGetArray(localxx,&avu);
92: for (j=0; j<gtdof; j++) {
93: ad_vustart[2*j] = avu[j];
94: ad_vustart[2*j+1] = 0.0;
95: }
96: VecRestoreArray(localxx,&avu);
98: if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
99: nI = 0;
100: for (stencil.k = info.zs; stencil.k<info.zs+info.zm; stencil.k++) {
101: for (stencil.j = info.ys; stencil.j<info.ys+info.ym; stencil.j++) {
102: for (stencil.i = info.xs; stencil.i<info.xs+info.xm; stencil.i++) {
103: for (stencil.c = 0; stencil.c<info.dof; stencil.c++) {
104: 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;
105: NLFNewton_DAAD(A,&info,&stencil,ad_vu,ad_vustart,nI,gI,residual[nI]);
106: nI++;
107: }
108: }
109: }
110: }
111: }
112: if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
113: nI = info.dof*info.xm*info.ym*info.zm - 1;
114: for (stencil.k = info.zs+info.zm-1; stencil.k>=info.zs; stencil.k--) {
115: for (stencil.j = info.ys+info.ym-1; stencil.j>=info.ys; stencil.j--) {
116: for (stencil.i = info.xs+info.xm-1; stencil.i>=info.xs; stencil.i--) {
117: for (stencil.c = info.dof-1; stencil.c>=0; stencil.c--) {
118: 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;
119: NLFNewton_DAAD(A,&info,&stencil,ad_vu,ad_vustart,nI,gI,residual[nI]);
120: nI--;
121: }
122: }
123: }
124: }
125: }
127: /* copy solution back into ghosted vector from derivative object */
128: VecGetArray(localxx,&av);
129: for (j=0; j<gtdof; j++) {
130: av[j] = ad_vustart[2*j];
131: }
132: VecRestoreArray(localxx,&av);
133: /* stick relaxed solution back into global solution */
134: DALocalToGlobal(A->da,localxx,INSERT_VALUES,xx);
135: }
138: VecRestoreArray(A->residual,&residual);
139: DARestoreLocalVector(A->da,&localxx);
140: DARestoreAdicMFArray(A->da,PETSC_TRUE,(void **)&ad_vu,(void**)&ad_vustart,>dof);
141: return(0);
142: }
143: EXTERN_C_END
148: int NLFDestroy_DAAD(NLF A)
149: {
150: int ierr;
153: DADestroy(A->da);
154: PetscFree(A);
155: return(0);
156: }
159: EXTERN_C_BEGIN
162: int NLFDAADSetDA_DAAD(NLF A,DA da)
163: {
164: int ierr;
167: A->da = da;
168: PetscObjectReference((PetscObject)da);
169: return(0);
170: }
171: EXTERN_C_END
173: EXTERN_C_BEGIN
176: int NLFDAADSetNewtonIterations_DAAD(NLF A,int its)
177: {
180: A->newton_its = its;
181: return(0);
182: }
183: EXTERN_C_END
185: EXTERN_C_BEGIN
188: int NLFDAADSetResidual_DAAD(NLF A,Vec residual)
189: {
191: A->residual = residual;
192: return(0);
193: }
194: EXTERN_C_END
197: EXTERN_C_BEGIN
200: int NLFDAADSetCtx_DAAD(NLF A,void *ctx)
201: {
203: A->ctx = ctx;
204: return(0);
205: }
206: EXTERN_C_END
208: EXTERN_C_BEGIN
211: int NLFCreate_DAAD(NLF *A)
212: {
213: int ierr;
216: PetscNew(struct NLF_DAAD,A);
217: (*A)->da = 0;
218: (*A)->ctx = 0;
219: (*A)->newton_its = 2;
220: return(0);
221: }
222: EXTERN_C_END