1 /* CalculiX - A 3-dimensional finite element program */
2 /* Copyright (C) 1998-2021 Guido Dhondt */
3
4 /* This program is free software; you can redistribute it and/or */
5 /* modify it under the terms of the GNU General Public License as */
6 /* published by the Free Software Foundation(version 2); */
7 /* */
8
9 /* This program is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
12 /* GNU General Public License for more details. */
13
14 /* You should have received a copy of the GNU General Public License */
15 /* along with this program; if not, write to the Free Software */
16 /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #include <stdio.h>
19 #include <math.h>
20 #include <stdlib.h>
21 #include "CalculiX.h"
22 #ifdef SPOOLES
23 #include "spooles.h"
24 #endif
25 #ifdef SGI
26 #include "sgi.h"
27 #endif
28 #ifdef TAUCS
29 #include "tau.h"
30 #endif
31
checkconvnet(ITG * icutb,ITG * iin,double * cam1t,double * cam1f,double * cam1p,double * cam2t,double * cam2f,double * cam2p,double * camt,double * camf,double * camp,ITG * icntrl,double * dtheta,double * ctrl,double * cam1a,double * cam2a,double * cama,double * vamt,double * vamf,double * vamp,double * vama,double * qa,double * qamt,double * qamf,double * ramt,double * ramf,double * ramp,ITG * iplausi,ITG * ichannel,ITG * iaxial)32 void checkconvnet(ITG *icutb, ITG *iin,
33 double *cam1t, double *cam1f, double *cam1p,
34 double *cam2t, double *cam2f, double *cam2p,
35 double *camt, double *camf, double *camp,
36 ITG *icntrl, double *dtheta, double *ctrl,
37 double *cam1a,double *cam2a,double *cama,
38 double *vamt, double *vamf, double *vamp, double *vama,
39 double *qa, double *qamt, double *qamf,
40 double *ramt, double *ramf, double *ramp, ITG *iplausi,
41 ITG *ichannel,ITG *iaxial){
42
43 ITG i0,ir,ip,ic,il,ig,ia,idivergence,iin_dyn,dyna_flag_1,dyna_flag_2;
44
45 double c2t,c2f,c2p,c2a,c1t,c1f,c1p,a2t,a2f,a2p,a2a,a1t,a1f,a1p,qamp=1.,
46 df,dc,db,dd,ran,can,rap,ea,cae,ral;
47
48 i0=ctrl[0];ir=ctrl[1];ip=ctrl[2];ic=ctrl[3];il=ctrl[4];ig=ctrl[5];ia=ctrl[7];
49 df=ctrl[10];dc=ctrl[11];db=ctrl[12];dd=ctrl[16];ran=ctrl[18];can=ctrl[19];
50 rap=ctrl[22];ea=ctrl[23];cae=ctrl[24];ral=ctrl[25];c1t=ctrl[32];c1f=ctrl[33];
51 c1p=ctrl[34];c2t=ctrl[35];c2f=ctrl[36];c2p=ctrl[37];c2a=ctrl[38];
52 a1t=ctrl[40];a1f=ctrl[41];a1p=ctrl[42];a2t=ctrl[43];a2f=ctrl[44],a2p=ctrl[45];
53 a2a=ctrl[46];
54
55 /* checks for dynamic convergence
56 - to avoid oscillations the check is done after a special number
57 inn_dyn of iterations */
58
59 iin_dyn=50;
60 if(*iin%iin_dyn==0){
61
62 /* criteria 1: change of sign */
63 dyna_flag_1=0;
64 if(*camt**cam1t>=0 && *camt**cam2t>=0){dyna_flag_1=dyna_flag_1;}
65 else{dyna_flag_1=dyna_flag_1+1;}
66 if(*camf**cam1f>=0 && *camf**cam2f>=0){dyna_flag_1=dyna_flag_1;}
67 else{dyna_flag_1=dyna_flag_1+1;}
68 if(*camp**cam1p>=0 && *camp**cam2p>=0){dyna_flag_1=dyna_flag_1;}
69 else{dyna_flag_1=dyna_flag_1+1;}
70 if(*cama**cam1a>=0 && *cama**cam2a>=0){dyna_flag_1=dyna_flag_1;}
71 else{dyna_flag_1=dyna_flag_1+1;}
72
73 /* criteria 2: progression check */
74 dyna_flag_2=0;
75 if(fabs(*camt)<=fabs(*cam1t) && fabs(*cam1t)<=fabs(*cam2t)){dyna_flag_2=dyna_flag_2;}
76 else{dyna_flag_2=dyna_flag_2+1;}
77 if(fabs(*camf)<=fabs(*cam1f) && fabs(*cam1f)<=fabs(*cam2f)){dyna_flag_2=dyna_flag_2;}
78 else{dyna_flag_2=dyna_flag_2+1;}
79 if(fabs(*camp)<=fabs(*cam1p) && fabs(*cam1p)<=fabs(*cam2p)){dyna_flag_2=dyna_flag_2;}
80 else{dyna_flag_2=dyna_flag_2+1;}
81 if(fabs(*cama)<=fabs(*cam1a) && fabs(*cam1a)<=fabs(*cam2a)){dyna_flag_2=dyna_flag_2;}
82 else{dyna_flag_2=dyna_flag_2+1;}
83
84 }
85
86
87 /* Das wird aus meiner Sicht nicht mehr benoetigt
88 if(*cam1t<*cam2t) {*cam2t=*cam1t;}
89 if(*cam1f<*cam2f) {*cam2f=*cam1f;}
90 if(*cam1p<*cam2p) {*cam2p=*cam1p;}
91 if(*cam1a<*cam2a) {*cam2a=*cam1a;}
92 */
93
94
95 /* check for convergence or divergence;
96 the convergence check consists of
97 - a comparison of the correction in
98 the latest network iteration with the change since the
99 start of the network calculations
100 - a comparison of the residual in the latest network
101 iteration with mean typical values of the equation terms */
102
103 if(*ichannel==1){*ramt=0.;*ramf=0.;*ramp=0.;}
104
105 if((fabs(*camt)<=c2t**vamt)&&(*ramt<c1t**qamt)&&(fabs(*camt)<=a2t)&&
106 (*ramt<a1t/(*iaxial))&&(fabs(*camf)<=c2f**vamf)&&(*ramf<c1f**qamf)&&
107 (fabs(*camf)<=a2f/(*iaxial))&&(*ramf<a1f/(*iaxial))&&
108 (fabs(*camp)<=c2p**vamp)&&(*ramp<c1p*qamp)&&(fabs(*camp)<a2p)&&(*ramp<a1p)&&
109 (fabs(*cama)<=c2a**vama)&&(fabs(*cama)<=a2a)&&(*iplausi==1)&&
110 (*iin>3)){
111
112 /* increment convergence reached */
113
114 printf(" flow network: convergence in gas iteration %" ITGFORMAT " \n\n",*iin);
115 *icntrl=1;
116 *icutb=0;
117 }
118
119 else {
120
121 idivergence=0;
122
123 /* divergence based on temperatures */
124
125 if((*iin>=20*i0)||(fabs(*camt)>1.e20)){
126 if((fabs(*cam1t)>=fabs(*cam2t))&&(fabs(*camt)>=fabs(*cam2t))&&(fabs(*camt)>c2t**vamt)){
127 idivergence=1;
128 }
129 }
130
131 /* divergence based on the mass flux */
132
133 if((*iin>=20*i0)||(fabs(*camf)>1.e20)){
134 if((fabs(*cam1f)>=fabs(*cam2f))&&(fabs(*camf)>=fabs(*cam2f))&&(fabs(*camf)>c2f**vamf)){
135 idivergence=1;
136 }
137 }
138
139 /* divergence based on pressures */
140
141 if((*iin>=20*i0)||(fabs(*camp)>1.e20)){
142 if((fabs(*cam1p)>=fabs(*cam2p))&&(fabs(*camp)>=fabs(*cam2p))&&(fabs(*camp)>c2p**vamp)){
143 idivergence=1;
144 }
145 }
146
147 /* divergence based on geometry */
148
149 if((*iin>=20*i0)||(fabs(*cama)>1.e20)){
150 if((fabs(*cam1a)>=fabs(*cam2a))&&(fabs(*cama)>=fabs(*cam2a))&&(fabs(*cama)>c2a**vama)){
151 idivergence=1;
152 }
153 }
154
155 /* divergence based on the number of iterations */
156
157 if(*iin>20*ic) idivergence=1;
158
159 /* divergence based on singular matrix or negative pressures */
160
161 if(*iin==0) idivergence=1;
162
163 if(idivergence==1){
164 *dtheta=*dtheta*df;
165 printf("\n network divergence; the under-relaxation parameter is decreased to %e\n",*dtheta);
166 printf(" the network iteration for the increment is reattempted\n\n");
167 *iin=0;
168 (*icutb)++;
169 if(*icutb>ia){
170 qa[2]=0.25;
171 *icntrl=1;
172 // printf("\n *ERROR: too many cutbacks\n");
173 // FORTRAN(stop,());
174 }
175 }else{
176 if(*iin%iin_dyn==0){
177 if(dyna_flag_1==0 && dyna_flag_2==0 && *iplausi==1){
178 printf(" good convergence --> *dtheta is increased %" ITGFORMAT "\n",*iin);
179 *dtheta=*dtheta*(1.2);
180 if(*dtheta>=1){
181 *dtheta=1.;
182 }
183 }
184 else if(dyna_flag_1!=0 && dyna_flag_2!=0 && *iplausi!=1){
185 printf(" bad convergence progression --> *dtheta is decreased %" ITGFORMAT "\n",*iin);
186 *dtheta=*dtheta*(0.8);
187 }
188 else{
189 printf(" no convergence\n\n");
190 }
191 }
192 else{
193 printf(" no convergence\n\n");
194 }
195 }
196 }
197 return;
198 }
199