# Diff of /trunk/paso/src/SolverFCT_solve.c

revision 1415 by ksteube, Thu Feb 21 04:57:17 2008 UTC revision 1812 by ksteube, Fri Sep 26 00:19:18 2008 UTC
# Line 1  Line 1
/* $Id:$ */
1
2  /*******************************************************  /*******************************************************
3   *  *
4   *       Copyright 2007,2008 by University of Queensland  * Copyright (c) 2003-2008 by University of Queensland
5   *  * Earth Systems Science Computational Center (ESSCC)
6   *                http://esscc.uq.edu_m.au  * http://www.uq.edu.au/esscc
7   *        Primary Business: Queensland, Australia  *
8   *  Licensed under the Open Software License version 3.0  * Primary Business: Queensland, Australia
9   *     http://www.opensource.org/licenses/osl-3.0.php  * Licensed under the Open Software License version 3.0
10   *  * http://www.opensource.org/licenses/osl-3.0.php
11   *******************************************************/  *
12    *******************************************************/
13
14
15  /**************************************************************/  /**************************************************************/
16
17  /* Paso: Flux correction transport solver  /* Paso: Flux correction transport solver
18   *   *
19   * solves Mu_t=Ku+q   * solves Mu_t=Ku+q
20   *        u(0) >= u_min   *        u(0) >=0
21   *   *
22   * Warning: the program assums sum_{j} k_{ij}=0!!!   * Warning: the program assums sum_{j} k_{ij}=0!!!
23   *   *
24  */  */
25  /**************************************************************/  /**************************************************************/
26
27  /* Author: l.gross@uq.edu_m.au */  /* Author: l.gross@uq.edu.au */
28
29  /**************************************************************/  /**************************************************************/
30
31  #include "Paso.h"  #include "Paso.h"
32  #include "Solver.h"  #include "Solver.h"
33  #include "SolverFCT.h"  #include "SolverFCT.h"
34    #include "PasoUtil.h"
35  #include "escript/blocktimer.h"  #include "escript/blocktimer.h"
36  #ifdef _OPENMP  #ifdef _OPENMP
37  #include <omp.h>  #include <omp.h>
# Line 38  Line 40
40  #include <mpi.h>  #include <mpi.h>
41  #endif  #endif
42
43    /*
44     * inserts the source term into the problem
45     */
46    void Paso_FCT_setSource(const dim_t n,const double *source, double* sourceN, double* sourceP)
47    {
48       dim_t i;
49       register double rtmp;
50       /*
51        * seperate source into positive and negative part:
52        */
53       #pragma omp parallel for private(i,rtmp)
54       for (i = 0; i < n; ++i) {
55           rtmp=source[i];
56           if (rtmp <0) {
57              sourceN[i]=-rtmp;
58              sourceP[i]=0;
59           } else {
60              sourceN[i]= 0;
61              sourceP[i]= rtmp;
62           }
63       }
64    }
65
66    err_t Paso_FCT_setUpRightHandSide(Paso_FCTransportProblem* fctp, const double dt, const double *u_m, Paso_Coupler* u_m_coupler,  double * z_m,
67                                      Paso_SystemMatrix* flux_matrix, Paso_Coupler* uTilde_coupler, const double *b,
68                                      Paso_Coupler* QN_coupler, Paso_Coupler* QP_coupler,
69                                      double *RN_m, Paso_Coupler* RN_m_coupler, double* RP_m, Paso_Coupler* RP_m_coupler, const double *sourceN,
70                                      Paso_Performance* pp)
71    {
72       dim_t i;
73       const dim_t n=Paso_SystemMatrix_getTotalNumRows(fctp->transport_matrix);
74       register double m, rtmp;
75       /* distribute u */
76       Paso_Coupler_startCollect(u_m_coupler,u_m);
77       Paso_Coupler_finishCollect(u_m_coupler);
78       /*
79        *  set the ant diffusion fluxes:
80        *
81        */
82       Paso_FCTransportProblem_setAntiDiffusionFlux(dt,fctp,flux_matrix,u_m_coupler);
83       /*
84        *  apply pre flux-correction: f_{ij}:=0 if f_{ij}*(\tilde{u}[i]- \tilde{u}[j])<=0
85        *
86        */
87       Paso_FCTransportProblem_applyPreAntiDiffusionCorrection(flux_matrix,uTilde_coupler);
88       /*
89        *  set flux limiters RN_m,RP_m
90        *
91        */
92       Paso_FCTransportProblem_setRs(flux_matrix,fctp->lumped_mass_matrix,QN_coupler,QP_coupler,RN_m,RP_m);
93       Paso_Coupler_startCollect(RN_m_coupler,RN_m);
94       Paso_Coupler_startCollect(RP_m_coupler,RP_m);
95        /*
96         * z_m[i]=b[i] - (m_i*u_m[i] - dt*theta*sum_{j<>i} l_{ij} (u_m[j]-u_m[i]) + dt q^-[i])
97         *
98         * note that iteration_matrix stores the negative values of the
99         * low order transport matrix l therefore a=dt*fctp->theta is used.
100         */
101       Paso_SolverFCT_setMuPaLuPbQ(z_m,fctp->lumped_mass_matrix, u_m_coupler,dt*fctp->theta,fctp->iteration_matrix,dt,sourceN);
102       /* z_m=b-z_m */
103       Paso_Update(n,-1.,z_m,1.,b);
104
105       Paso_Coupler_finishCollect(RN_m_coupler);
106       Paso_Coupler_finishCollect(RP_m_coupler);
107       /* add corrected fluxes into z_m */
108       Paso_FCTransportProblem_addCorrectedFluxes(z_m,flux_matrix,RN_m_coupler,RP_m_coupler);
109       return NO_ERROR;
110    }
111
112    void Paso_SolverFCT_solve(Paso_FCTransportProblem* fctp, double* u, double dt, double* source, Paso_Options* options) {
113       const dim_t FAILURES_MAX=5;
114       err_t error_code;
115       dim_t m,n_substeps, i_substeps, Failed, i, iter;
116       err_t errorCode;
117       double *z_m=NULL, *b_n=NULL, *sourceP=NULL, *sourceN=NULL, *uTilde_n=NULL, *QN_n=NULL, *QP_n=NULL, *RN_m=NULL, *RP_m=NULL, *du_m=NULL;
118       Paso_Coupler *QN_n_coupler=NULL, *QP_n_coupler=NULL, *RN_m_coupler=NULL, *RP_m_coupler=NULL, *uTilde_n_coupler=NULL, *u_m_coupler=NULL;
119       Paso_SystemMatrix *flux_matrix_m=NULL;
120       double dt_max, dt2,t, norm_u_m, omega, norm_du_m, tol;
121       register double mass, rtmp;
122       const dim_t n=Paso_SystemMatrix_getTotalNumRows(fctp->transport_matrix);
123       dim_t blockSize=Paso_FCTransportProblem_getBlockSize(fctp);
124       const double atol=options->absolute_tolerance;
125       const double rtol=options->tolerance;
126       const dim_t max_m=options->iter_max;
127       Paso_Performance pp;
128       bool_t converged=FALSE, max_m_reached=FALSE;
129       if (dt<=0.) {
130           Paso_setError(TYPE_ERROR,"Paso_SolverFCT_solve: dt must be positive.");
131       }
132       dt_max=Paso_FCTransportProblem_getSafeTimeStepSize(fctp);
133       /*
134        *  allocate memory
135        *
136        */
137       z_m=TMPMEMALLOC(n,double);
138       Paso_checkPtr(z_m);
139       du_m=TMPMEMALLOC(n,double);
140       Paso_checkPtr(du_m);
141       b_n=TMPMEMALLOC(n,double);
142       Paso_checkPtr(b_n);
143       sourceP=TMPMEMALLOC(n,double);
144       Paso_checkPtr(sourceP);
145       sourceN=TMPMEMALLOC(n,double);
146       Paso_checkPtr(sourceN);
147       uTilde_n=TMPMEMALLOC(n,double);
148       Paso_checkPtr(uTilde_n);
149       QN_n=TMPMEMALLOC(n,double);
150       Paso_checkPtr(QN_n);
151       QP_n=TMPMEMALLOC(n,double);
152       Paso_checkPtr(QP_n);
153       RN_m=TMPMEMALLOC(n,double);
154       Paso_checkPtr(RN_m);
155       RP_m=TMPMEMALLOC(n,double);
156       Paso_checkPtr(RP_m);
157       QN_n_coupler=Paso_Coupler_alloc(Paso_FCTransportProblem_borrowConnector(fctp),blockSize);
158       QP_n_coupler=Paso_Coupler_alloc(Paso_FCTransportProblem_borrowConnector(fctp),blockSize);
159       RN_m_coupler=Paso_Coupler_alloc(Paso_FCTransportProblem_borrowConnector(fctp),blockSize);
160       RP_m_coupler=Paso_Coupler_alloc(Paso_FCTransportProblem_borrowConnector(fctp),blockSize);
161       uTilde_n_coupler=Paso_Coupler_alloc(Paso_FCTransportProblem_borrowConnector(fctp),blockSize);
162       u_m_coupler=Paso_Coupler_alloc(Paso_FCTransportProblem_borrowConnector(fctp),blockSize);
163       flux_matrix_m=Paso_SystemMatrix_alloc(fctp->transport_matrix->type,
164                                                     fctp->transport_matrix->pattern,
165                                                     fctp->transport_matrix->row_block_size,
166                                                     fctp->transport_matrix->col_block_size);
167
168       if (Paso_noError()) {
169           /*
170            *    Preparation:
171            *
172            */
173           Paso_FCT_setSource(n, source, sourceN, sourceP);
174           /*
175            * let the show begin!!!!
176            *
177            */
178            t=0;
179            i_substeps=0;
180            Paso_Copy(n,u,fctp->u);
181            norm_u_m=Paso_lsup(n,u, fctp->mpi_info);
182            /* while(i_substeps<n_substeps && Paso_noError()) { */
183            if (fctp->dt_max < LARGE_POSITIVE_FLOAT) {
184                dt2=MIN(dt_max,dt);
185            } else {
186                 dt2=dt;
187            }
188            while(t<dt && Paso_noError()) {
189                printf("substep step %d at t=%e (step size= %e)\n",i_substeps+1,t+dt2,dt2);
190                Paso_FCT_setUp(fctp,dt2,sourceN,sourceP,b_n,uTilde_n,uTilde_n_coupler,QN_n,QN_n_coupler,QP_n,QP_n_coupler,
191                               options,&pp);
192                /* now the iteration starts */
193                m=0;
194                converged=FALSE;
195                max_m_reached=FALSE;
196                /* tolerance? */
197                while ( (!converged) && (! max_m_reached) && Paso_noError()) {
198                        /* set z_m */
199                        Paso_FCT_setUpRightHandSide(fctp,dt2,u,u_m_coupler,z_m,flux_matrix_m,uTilde_n_coupler,b_n,
200                                      QN_n_coupler,QP_n_coupler,RN_m,RN_m_coupler,RP_m,RP_m_coupler,sourceN,&pp);
201                        /*
202                         * now we solve the linear system to get the correction dt:
203                         *
204                         */
205                         if (fctp->theta > 0) {
206                              omega=1./(dt2*fctp->theta);
207                              Paso_Solver_solvePreconditioner(fctp->iteration_matrix,du_m,z_m);
208                              Paso_Update(n,1.,u,omega,du_m);
209                         } else {
210                              omega=1;
211                              #pragma omp parallel for private(i,mass,rtmp)
212                              for (i = 0; i < n; ++i) {
213                                  mass=fctp->lumped_mass_matrix[i];
214                                  if (ABS(mass)>0.) {
215                                      rtmp=z_m[i]/mass;
216                                  } else {
217                                      rtmp=0;
218                                  }
219                                  du_m[i]=rtmp;
220                                  u[i]+=rtmp;
221                              }
222                       }
223                       norm_u_m=Paso_lsup(n,u, fctp->mpi_info);
224                       norm_du_m=Paso_lsup(n,du_m, fctp->mpi_info)*omega;
225                       printf("iteration step %d completed: norm increment= %e (tolerance = %e)\n",m+1, norm_du_m, rtol * norm_u_m + atol);
226
227                       max_m_reached=(m>max_m);
228                       converged=(norm_du_m <= rtol * norm_u_m + atol);
229                       m++;
230                }
231                if (converged) {
232                        Failed=0;
233                        /* #pragma omp parallel for schedule(static) private(i) */
234                        Paso_Copy(n,fctp->u,u);
235                        i_substeps++;
236                        t+=dt2;
237                        if (fctp->dt_max < LARGE_POSITIVE_FLOAT) {
238                           dt2=MIN3(dt_max,dt2*1.5,dt-t);
239                        } else {
240                           dt2=MIN(dt2*1.5,dt-t);
241                        }
242                } else if (max_m_reached) {
243                        /* if FAILURES_MAX failures in a row: give up */
244                        if (Failed > FAILURES_MAX) {
245                           Paso_setError(VALUE_ERROR,"Paso_SolverFCT_solve: no convergence after time step reduction.");
246                        } else {
247                           printf("no convergence in Paso_Solver_NewtonGMRES: Trying smaller time step size.");
248                           dt2=dt*0.5;
249                           Failed++;
250                        }
251                }
252
253          }
254          /*
255           *  clean-up:
256           *
257           */
258          MEMFREE(z_m);
259          MEMFREE(du_m);
260          TMPMEMFREE(b_n);
261          Paso_SystemMatrix_free(flux_matrix_m);
262          TMPMEMFREE(sourceP);
263          TMPMEMFREE(sourceN);
264          TMPMEMFREE(uTilde_n);
265          TMPMEMFREE(QN_n);
266          TMPMEMFREE(QP_n);
267          TMPMEMFREE(RN_m);
268          TMPMEMFREE(RP_m);
269          Paso_Coupler_free(QN_n_coupler);
270          Paso_Coupler_free(QP_n_coupler);
271          Paso_Coupler_free(RN_m_coupler);
272          Paso_Coupler_free(RP_m_coupler);
273          Paso_Coupler_free(uTilde_n_coupler);
274          Paso_Coupler_free(u_m_coupler);
275          options->absolute_tolerance=atol;
276          options->tolerance=rtol;
277       }
278    }
279  double Paso_FCTransportProblem_getSafeTimeStepSize(Paso_FCTransportProblem* fctp)  double Paso_FCTransportProblem_getSafeTimeStepSize(Paso_FCTransportProblem* fctp)
280  {  {
281     dim_t i, n_rows;     dim_t i, n;
282     double dt_max, dt_max_loc;     double dt_max, dt_max_loc;
283     register double rtmp1,rtmp2;     register double l_ii,m;
284     n_rows=Paso_SystemMatrix_getTotalNumRows(fctp->transport_matrix);     n=Paso_SystemMatrix_getTotalNumRows(fctp->transport_matrix);
285     if (! fctp->valid_matrices) {     if (! fctp->valid_matrices) {
286          fctp->dt_max=LARGE_POSITIVE_FLOAT;          fctp->dt_max=LARGE_POSITIVE_FLOAT;

287          /* extract the row sum of the advective part */          /* extract the row sum of the advective part */
288          Paso_SystemMatrix_rowSum(fctp->mass_matrix,fctp->lumped_mass_matrix);          Paso_SystemMatrix_rowSum(fctp->mass_matrix,fctp->lumped_mass_matrix);
289
# Line 61  double Paso_FCTransportProblem_getSafeTi Line 297  double Paso_FCTransportProblem_getSafeTi
297              #pragma omp parallel private(dt_max_loc)              #pragma omp parallel private(dt_max_loc)
298              {              {
299                 dt_max_loc=LARGE_POSITIVE_FLOAT;                 dt_max_loc=LARGE_POSITIVE_FLOAT;
300                 #pragma omp for schedule(static) private(i,rtmp1,rtmp2)                 #pragma omp for schedule(static) private(i,l_ii,m)
301                 for (i=0;i<n_rows;++i) {                 for (i=0;i<n;++i) {
302                      rtmp1=fctp->main_diagonal_low_order_transport_matrix[i];                      l_ii=fctp->main_diagonal_low_order_transport_matrix[i];
303                      rtmp2=fctp->lumped_mass_matrix[i];                      m=fctp->lumped_mass_matrix[i];
304                      if ( (rtmp1<0 && rtmp2>=0.) || (rtmp1>0 && rtmp2<=0.) ) {                      if ( (l_ii<0 && m>0.) || (l_ii>0 && m<0) ) {
305                          dt_max_loc=MIN(dt_max_loc,-rtmp2/rtmp1);                          dt_max_loc=MIN(dt_max_loc,-m/l_ii);
306                      }                      }
307                  }                  }
308                  #pragma omp critical                  #pragma omp critical
# Line 90  double Paso_FCTransportProblem_getSafeTi Line 326  double Paso_FCTransportProblem_getSafeTi
326     }     }
327     return fctp->dt_max;     return fctp->dt_max;
328  }  }
329    void Paso_FCT_setUp(Paso_FCTransportProblem* fctp, const double dt, const double *sourceN, const double *sourceP, double* b, double* uTilde,
330                         Paso_Coupler* uTilde_coupler, double *QN, Paso_Coupler* QN_coupler, double *QP, Paso_Coupler* QP_coupler,
331                         Paso_Options* options, Paso_Performance* pp)
332    {
333  void Paso_SolverFCT_solve(Paso_FCTransportProblem* fctp, double* u, double dt, double* source, Paso_Options* options) {     dim_t i;
334       const dim_t n=Paso_SystemMatrix_getTotalNumRows(fctp->transport_matrix);
335     index_t i, j;     double omega, factor;
336     int n_substeps,n, m;     register double m, u_tilde_i, rtmp4;
337     double dt_max, omega, dt2,t;     /* distribute u */
338     double local_norm[2],norm[2],local_norm_u,local_norm_du,norm_u,norm_du, tolerance;     Paso_Coupler_startCollect(fctp->u_coupler,fctp->u);
339     register double rtmp1,rtmp2,rtmp3,rtmp4, rtmp;     Paso_Coupler_finishCollect(fctp->u_coupler);
340     double *b_n=NULL, *sourceP=NULL, *sourceN=NULL, *uTilde_n=NULL, *QN_n=NULL, *QP_n=NULL, *RN_m=NULL, *RP_m=NULL, *z_m=NULL, *du_m=NULL;     /*
341     Paso_SystemMatrix *flux_matrix=NULL;      * b^n[i]=m u^n[i] + dt*(1-theta) sum_{j <> i} l_{ij}*(u^n[j]-u^n[i]) + dt*sourceP[i]
342     dim_t n_rows=Paso_SystemMatrix_getTotalNumRows(fctp->transport_matrix);      *
343     bool_t converged;      * note that iteration_matrix stores the negative values of the
344     if (dt<=0.) {      * low order transport matrix l therefore a=-dt*(1-fctp->theta) is used.
Paso_setError(TYPE_ERROR,"Paso_SolverFCT_solve: dt must be positive.");
}
dt_max=Paso_FCTransportProblem_getSafeTimeStepSize(fctp);
/*
*  allocate memory
345      *      *
346      */      */
347     Paso_SystemMatrix_allocBuffer(fctp->iteration_matrix);      Paso_SolverFCT_setMuPaLuPbQ(b,fctp->lumped_mass_matrix,fctp->u_coupler,
348     b_n=TMPMEMALLOC(n_rows,double);                                 -dt*(1-fctp->theta),fctp->iteration_matrix,dt,sourceP);
349     Paso_checkPtr(b_n);     /*
350     sourceP=TMPMEMALLOC(n_rows,double);      *   uTilde[i]=b[i]/m[i]
351     Paso_checkPtr(sourceP);      *
352     sourceN=TMPMEMALLOC(n_rows,double);      *   fctp->iteration_matrix[i,i]=m[i]/(dt theta) + \frac{1}{\theta} \frac{q^-[i]}-l[i,i]
353     Paso_checkPtr(sourceN);      *
354     uTilde_n=TMPMEMALLOC(n_rows,double);      */
355     Paso_checkPtr(uTilde_n);      if (fctp->theta > 0) {
356     QN_n=TMPMEMALLOC(n_rows,double);           Paso_solve_free(fctp->iteration_matrix);
357     Paso_checkPtr(QN_n);           omega=1./(dt*fctp->theta);
358     QP_n=TMPMEMALLOC(n_rows,double);           factor=dt*omega;
359     Paso_checkPtr(QP_n);           #pragma omp parallel for private(i,m,u_tilde_i,rtmp4)
360     RN_m=TMPMEMALLOC(n_rows,double);           for (i = 0; i < n; ++i) {
361     Paso_checkPtr(RN_m);                m=fctp->lumped_mass_matrix[i];
362     RP_m=TMPMEMALLOC(n_rows,double);                if (ABS(m)>0.) {
363     Paso_checkPtr(RP_m);                   u_tilde_i=b[i]/m;
364     z_m=TMPMEMALLOC(n_rows,double);                } else {
365     Paso_checkPtr(z_m);                   u_tilde_i=fctp->u[i];
366     du_m=TMPMEMALLOC(n_rows,double);                }
367     Paso_checkPtr(du_m);                rtmp4=m*omega-fctp->main_diagonal_low_order_transport_matrix[i];
368     flux_matrix=Paso_SystemMatrix_alloc(fctp->transport_matrix->type,                if (ABS(u_tilde_i)>0) rtmp4+=sourceN[i]*factor/u_tilde_i;
369                                         fctp->transport_matrix->pattern,                fctp->iteration_matrix->mainBlock->val[fctp->main_iptr[i]]=rtmp4;
370                                         fctp->transport_matrix->row_block_size,                uTilde[i]=u_tilde_i;
371                                         fctp->transport_matrix->col_block_size);           }
372     if (Paso_noError()) {           Performance_startMonitor(pp,PERFORMANCE_PRECONDITIONER_INIT);
373         Paso_SystemMatrix_allocBuffer(flux_matrix);           Paso_Solver_setPreconditioner(fctp->iteration_matrix,options);
374         Paso_SystemMatrix_allocBuffer(fctp->iteration_matrix);           Performance_stopMonitor(pp,PERFORMANCE_PRECONDITIONER_INIT);
375         /*      } else {
376          *    Preparation:          #pragma omp parallel for private(i,m,u_tilde_i)
377          *          for (i = 0; i < n; ++i) {
378          */              m=fctp->lumped_mass_matrix[i];
379                    if (ABS(m)>0.) {
380         /* decide on substepping */                  u_tilde_i=b[i]/m;
381         if (fctp->dt_max < LARGE_POSITIVE_FLOAT) {              } else {
382            n_substeps=ceil(dt/dt_max);                  u_tilde_i=fctp->u[i];
383         } else {              }
384            n_substeps=1;              uTilde[i]=u_tilde_i;
}
dt2=dt/n_substeps;
printf("%d time steps of size is %e (theta = %e, dt_max=%e).\n",n_substeps, dt2,fctp->theta, dt_max);
/*
* seperate source into positive and negative part:
*/
#pragma omp parallel for private(i,rtmp)
for (i = 0; i < n_rows; ++i) {
rtmp=source[i];
if (rtmp <0) {
sourceN[i]=-rtmp;
sourceP[i]=0;
} else {
sourceN[i]= 0;
sourceP[i]= rtmp;
}
385          }          }
386  /*        for (i = 0; i < n_rows; ++i) printf("%d : %e \n",i,source[i],sourceP[i],sourceN[i]) */          /* no update of iteration_matrix required! */
387          /*      } /* end (fctp->theta > 0) */
* let the show begin!!!!
*
*/
t=dt2;
n=0;
tolerance=options->tolerance;
while(n<n_substeps && Paso_noError()) {
printf("substep step %d at t=%e\n",n+1,t);
#pragma omp parallel for private(i)
for (i = 0; i < n_rows; ++i) {
u[i]=fctp->u[i];
}
/*
* b^n[i]=m u^n[i] + dt2*(1-theta) sum_{j <> i} l_{ij}*(u^n[j]-u^n[i]) + dt2*sourceP[i]
*
* note that iteration_matrix stores the negative values of the
* low order transport matrix l therefore a=-dt2*(1-fctp->theta) is used.
*
*/
Paso_SolverFCT_setMuPaLuPbQ(b_n,fctp->lumped_mass_matrix,u,
-dt2*(1-fctp->theta),fctp->iteration_matrix,dt2,sourceP);
/*
*   uTilde_n[i]=b[i]/m[i]
*
*   a[i,i]=m[i]/(dt2 theta) + \frac{1}{\theta} \frac{q^-[i]}-l[i,i]
*
*/
if (fctp->theta > 0) {
Paso_solve_free(fctp->iteration_matrix);
omega=1./(dt2*fctp->theta);
rtmp2=dt2*omega;
#pragma omp parallel for private(i,rtmp,rtmp3,rtmp4)
for (i = 0; i < n_rows; ++i) {
rtmp=fctp->lumped_mass_matrix[i];
if (ABS(rtmp)>0.) {
rtmp3=b_n[i]/rtmp;
} else {
rtmp3=u[i];
}
rtmp4=rtmp*omega-fctp->main_diagonal_low_order_transport_matrix[i];
if (ABS(rtmp3)>0) rtmp4+=sourceN[i]*rtmp2/rtmp3;
fctp->iteration_matrix->mainBlock->val[fctp->main_iptr[i]]=rtmp4;
uTilde_n[i]=rtmp3;
}
} else {
#pragma omp parallel for private(i,rtmp,rtmp3)
for (i = 0; i < n_rows; ++i) {
rtmp=fctp->lumped_mass_matrix[i];
if (ABS(rtmp)>0.) {
rtmp3=b_n[i]/rtmp;
} else {
rtmp3=u[i];
}
uTilde_n[i]=rtmp3;
}
omega=1.;
/* no update of iteration_matrix retquired! */
} /* end (fctp->theta > 0) */
/*
* calculate QP_n[i] max_{j} (\tilde{u}[j]- \tilde{u}[i] )
*           QN_n[i] min_{j} (\tilde{u}[j]- \tilde{u}[i] )
*
*/
Paso_SolverFCT_setQs(uTilde_n,QN_n,QP_n,fctp->iteration_matrix);
/*
* now we enter the mation on a time-step:
*
*/
m=0;
converged=FALSE;
while ( (!converged) && (m<500) && Paso_noError()) {
printf("iteration step %d\n",m+1);
/*
*  set the ant diffusion fluxes:
*
*/
Paso_FCTransportProblem_setAntiDiffusionFlux(dt2,fctp,flux_matrix,u,fctp->u);
/*
*  apply pre flux-correction: f_{ij}:=0 if f_{ij}*(\tilde{u}[i]- \tilde{u}[j])<=0
*
*  this is not entirely correct!!!!!
*
*/
Paso_FCTransportProblem_applyPreAntiDiffusionCorrection(flux_matrix,uTilde_n);
/*
*  set flux limms RN_m,RP_m
*
*/
Paso_FCTransportProblem_setRs(flux_matrix,fctp->lumped_mass_matrix,QN_n,QP_n,RN_m,RP_m);
/*
* z_m[i]=b_n[i] - (m_i*u[i] - dt2*theta*sum_{j<>i} l_{ij} (u[j]-u[i]) + dt2 q^-[i])
*
* note that iteration_matrix stores the negative values of the
* low order transport matrix l therefore a=dt2*fctp->theta is used.
*/

Paso_SolverFCT_setMuPaLuPbQ(z_m,fctp->lumped_mass_matrix,u,
dt2*fctp->theta,fctp->iteration_matrix,dt2,sourceN);
#pragma omp parallel for private(i)
for (i = 0; i < n_rows; ++i) z_m[i]=b_n[i]-z_m[i];

/* add corrected fluxes into z_m */
Paso_FCTransportProblem_addCorrectedFluxes(z_m,flux_matrix,RN_m,RP_m);
/*
* now we solve the linear system to get the correction dt2:
*
*/
if (fctp->theta > 0) {
/*  set the right hand side of the linear system: */
options->tolerance=1.e-2;
Paso_solve(fctp->iteration_matrix,du_m,z_m,options);
/* TODO: check errors ! */
} else {
#pragma omp parallel for private(i,rtmp,rtmp1)
for (i = 0; i < n_rows; ++i) {
rtmp=fctp->lumped_mass_matrix[i];
if (ABS(rtmp)>0.) {
rtmp1=z_m[i]/rtmp;
} else {
rtmp1=0;
}
du_m[i]=rtmp1;
}
}
/*
* update u and calculate norm of du_m and the new u:
*
*/
norm_u=0.;
norm_du=0.;
#pragma omp parallel private(local_norm_u,local_norm_du)
{
local_norm_u=0.;
local_norm_du=0.;
#pragma omp for schedule(static) private(i)
for (i=0;i<n_rows;++i) {
u[i]+=omega*du_m[i];
local_norm_u=MAX(local_norm_u,ABS(u[i]));
local_norm_du=MAX(local_norm_du,ABS(du_m[i]));
}
#pragma omp critical
{
norm_u=MAX(norm_u,local_norm_u);
norm_du=MAX(norm_du,local_norm_du);
}
}
#ifdef PASO_MPI
local_norm[0]=norm_u;
local_norm[1]=norm_du;
MPI_Allreduce(local_norm,norm, 2, MPI_DOUBLE, MPI_MAX, fctp->mpi_info->comm);
norm_u=norm[0];
norm_du=norm[1];
#endif
norm_du*=omega;
converged=(norm_du <= tolerance * norm_u);
m++;
printf("iteration step %d: norm u and du_m : %e %e\n",m,norm_u,norm_du);
/* TODO: check if du_m has been redu_mced */
} /* end of inner iteration */
#pragma omp parallel for schedule(static) private(i)
for (i=0;i<n_rows;++i) fctp->u[i]=u[i];
n++;
} /* end of time integration */
#pragma omp parallel for schedule(static) private(i)
for (i=0;i<n_rows;++i) u[i]=fctp->u[i]+fctp->u_min;
/* TODO: update u_min ? */
388
389          }      /* distribute uTilde: */
390          /*      Paso_Coupler_startCollect(uTilde_coupler,uTilde);
391           *  clean-up:      Paso_Coupler_finishCollect(uTilde_coupler);
392           *      /*
393           */       * calculate QP[i] max_{j} (\tilde{u}[j]- \tilde{u}[i] )
394          TMPMEMFREE(b_n);       *           QN[i] min_{j} (\tilde{u}[j]- \tilde{u}[i] )
395          Paso_SystemMatrix_free(flux_matrix);       *
396          TMPMEMFREE(sourceP);       */
397          TMPMEMFREE(sourceN);       Paso_SolverFCT_setQs(uTilde_coupler,QN,QP,fctp->iteration_matrix);
398          TMPMEMFREE(uTilde_n);       Paso_Coupler_startCollect(QN_coupler,QN);
399          TMPMEMFREE(QN_n);       Paso_Coupler_startCollect(QP_coupler,QP);
400          TMPMEMFREE(QP_n);       Paso_Coupler_finishCollect(QN_coupler);
401          TMPMEMFREE(RN_m);       Paso_Coupler_finishCollect(QP_coupler);
TMPMEMFREE(RP_m);
TMPMEMFREE(z_m);
TMPMEMFREE(du_m);
402  }  }

Legend:
 Removed from v.1415 changed lines Added in v.1812

 ViewVC Help Powered by ViewVC 1.1.26