-
Notifications
You must be signed in to change notification settings - Fork 119
Expand file tree
/
Copy pathmba_analytic.f
More file actions
294 lines (231 loc) · 7.21 KB
/
Copy pathmba_analytic.f
File metadata and controls
294 lines (231 loc) · 7.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
C ==========================================================
Subroutine mbaAnalytic(
C ==========================================================
c group (M)
& nP, MaxP, nF, MaxF, nE, MaxE, nPv,
& XYP, IPF, IPE, IPV,
& CrvFunction, ParCrv, iFnc,
& nEStar,
c group (D)
& nFv, nEv, IFV, IEV, lbE,
& flagAuto, status,
c group (Q)
& MaxSkipE, MaxQItr,
& MetricFunction, Quality, rQuality,
c group (W)
& MaxWr, MaxWi, rW, iW,
& iPrint, iERR)
C ==========================================================
include 'lintrp.fd'
include 'status.fd'
C ==========================================================
C VARIABLES & PARAMETER are described in mba_nodal.f
C
C MetricFunction - integer function created by the user (see
C example in file forlibmba.f)
C
C Integer Function MetricFunction(x, y, z, Metric)
C
C This routine creates a metric at the given point (x,y, z). The
C metric is a 2x2 positive definite symmetric tensor:
C
C M11 M12
C Metric =
C M12 M22
C
C Only the upper triangular part of array Metric must be defined.
C
C
C *** Authors: K. Lipnikov (lipnikov@hotmail.com)
C Y. Vassilevski (vasilevs@dodo.inm.ras.ru)
C ==========================================================
C group (M)
C Integer MaxP, MaxF, MaxE, MaxFnc
real XYP(2, *)
Integer IPE(3, *), IPF(4, *), IPV(*)
EXTERNAL CrvFunction
real ParCrv(2, *)
Integer iFnc(*)
C group (D)
Integer nFv, nEv
Integer IFV(*), IEV(*), lbE(*)
Logical flagAuto
Integer status
C group (Q)
Integer MaxSkipE, MaxQItr
real Quality, rQuality
Logical flagAnalytic
Integer MetricFunction
EXTERNAL MetricFunction
C group (W)
real rW(*)
Integer iW(*)
C group (Local variables)
real hStar
C ==========================================================
C group (Common blocks)
Integer iDomBnd, iMatBnd
Common /aniBND/ iDomBnd, iMatBnd
real refXYP(2), scaXYP(2)
Common /rescale/refXYP, scaXYP
C ==========================================================
iERR = 0
Do i = 1, 2
refXYP(i) = 0D0
scaXYP(i) = 1D0
End do
c ... refine initial mesh when nE is very small
c ... it increases robustness of the code
Do while(nE < nEStar / 15 .AND. nE.LE.500 .AND. nEv+nFv.EQ.0)
iIFE = 1
iiW = iIFE + 3 * nE
nWi = iiW + 3 * nE + nP
If(nWi.GT.MaxWi) goto 100
iSol = 1
nWr = iSol + MaxP
If(nWr.GT.MaxWr) goto 100
If(iPrint.GE.1) Write(*,5001) nP, nE
Do i = 1, nP
rW(iSol + i - 1) = 0D0
End do
Call uniformRefinement(
& nP, MaxP, nF, MaxF, nE, MaxE,
& XYP, IPF, IPE, lbE,
& CrvFunction, ParCrv, iFnc, iW(iIFE),
& rW(iSol), 1, iW(iiW), MaxWi)
End do
100 miLINTRP = 10 * nP + 3 * nE + 6
mrLINTRP = 4 * nP + MaxH + 4
inEt = 1
inStept = inEt + MaxF
inL2t = inStept + 4 * MaxF
iLFnc = inL2t + MaxF
iILt = iLFnc + MaxF
iL1Et = iILt + MaxF
iL2Et = iL1Et + 2 * MaxF
iIHolP = iL2Et + 2 * MaxF
iIHolF = iIHolP + MaxP
iIHolE = iIHolF + MaxF
iICP = iIHolE + MaxE
iIEP = iICP + MaxP
iIFE = iIEP + MaxP
iIEE = iIFE + 3 * MaxE
iL1E = iIEE + 3 * MaxE
iL2E = iL1E + 2 * MaxE
iIPEw = iL2E + 2 * MaxE
iiSE = iIPEw + 3 * nE
iIEPw = iiSE + miLINTRP
c ... we need twice less memory for backReferences
inEPw = iIEPw + max(6 * nE, 4 * MaxF)
nWi = inEPw + max(3 * MaxP, 2 * MaxF)
iHesP = 1
itE = iHesP + 3 * MaxP
idG = itE + MaxF
iqE = idG + MaxP
iHesPw = iqE + MaxE
iXYPw = iHesPw + 3 * nP
irSE = iXYPw + 2 * nP
nWr = irSE + max(mrLINTRP, max(nE, MaxF))
iW(1) = nWi
iW(2) = nWr
If(nWi.GT.MaxWi) Then
iERR = 1001
goto 1000
End if
If(nWr.GT.MaxWr) Then
iERR = 1002
goto 1000
End if
Do n = 1, nWr
rW(n) = 0D0
End do
Do n = 1, nWi
iW(n) = 0
End do
c ... compute the analytic metric
Call iniQ_analytic(nP, XYP, MetricFunction, rW(iHesP))
c ... scale geometry to unit cube
Call scale2Square(nP, XYP, .TRUE.)
c ... print Ani2D header
If(iPrint.GE.1) Write(*, 5004) Quality, nEStar, MaxQItr
c ... set up default status
Call setStatus(flagAuto, status, iPrint)
c ... call the main module
flagAnalytic = .TRUE.
Call ani2(
c group (M)
& nP, MaxP, nF, MaxF, nE, MaxE, nPv,
& XYP, IPF, IPE, IPV,
& CrvFunction, ParCrv, iFnc,
& nEStar, hStar,
& iW(iICP), iW(iIEP),
& iW(iIFE), iW(iIEE),
& iW(iL1E), iW(iL2E),
& iW(iIHolP), iW(iIHolF), iW(iIHolE),
& iW(iIEPw), iW(inEPw),
& iW(iIPEw), iW(iiSE),
c group (Dev)
& nFv, nEv, IFV, IEV, lbE,
& flagAuto, status,
c group (CRV)
& iW(iL1Et), iW(iL2Et), rW(itE),
& iW(inL2t), iW(inStept), iW(inEt),
& iW(iLFnc), iW(iILt),
c group (Q)
& MaxSkipE, MaxQItr, nQItr,
& rW(iHesP), Quality, rQuality,
& rW(idG), rW(iqE), rW(iXYPw), rW(iHesPw), rW(irSE),
& MetricFunction, flagAnalytic,
c group (ERR)
& iPrint, iERR)
c ... rescale geometry back
Call scale2Square(nP, XYP, .FALSE.)
c ... returning sadditional information
Do n = 1, nP
iW(n) = iW(iICP + n - 1)
End do
iW(nP + 1) = nQItr
rW(1) = 0D0
rW(2) = rQuality
rW(3) = hStar
1000 If(iERR.EQ.0 .OR. iERR.EQ.1000) Return
Call errMes(iERR, 'mbaMetric',
& 'See error.f for error description')
Return
5001 Format('Refining mesh:', I6, ' pts and', I7, ' elements')
5004 Format(/,
& 'STONE FLOWER! (1997-2007), version 2.0', /,
& 'Target: Quality', F5.2, ' with', I8,
& ' triangles for at most', I8, ' iterations')
End
C ==========================================================
Subroutine iniQ_analytic(nP, XYP, MetricFunction, HesP)
C ==========================================================
C Three Fortran routines below create a metric field which
C is 2x2 variable positive definite symmetric tensor HesP,
C F(x,y) H(x,y)
C HesP =
C H(x,y) G(x,y)
C ==========================================================
C group (M)
real XYP(2, *)
C group (Q)
Integer MetricFunction
EXTERNAL MetricFunction
real HesP(3, *)
C group (Local variables)
real x, y, Metric(2, 2)
C ==========================================================
real refXYP(2), scaXYP(2)
Common /rescale/refXYP, scaXYP
C ==========================================================
Do n = 1, nP
x = refXYP(1) + XYP(1, n) * scaXYP(1)
y = refXYP(2) + XYP(2, n) * scaXYP(2)
i = MetricFunction(x, y, Metric)
HesP(1, n) = Metric(1, 1)
HesP(2, n) = Metric(2, 2)
HesP(3, n) = Metric(1, 2)
End do
Return
End