• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

trixi-framework / HOHQMesh / 30318764346

28 Jul 2026 12:55AM UTC coverage: 76.972% (+1.1%) from 75.909%
30318764346

Pull #166

github

web-flow
Merge 3346edfd3 into 955f92dca
Pull Request #166: Add L2/H1 boundary optimization

1631 of 1964 new or added lines in 40 files covered. (83.04%)

48 existing lines in 4 files now uncovered.

9563 of 12424 relevant lines covered (76.97%)

634449.32 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.86
/Source/IO/Scanning.f90
1
!
2
!////////////////////////////////////////////////////////////////////////
3
!
4
!      Scanning.f90
5
!      Created: June 23, 2026 at 10:13 AM
6
!      By: David Kopriva
7
!
8
!////////////////////////////////////////////////////////////////////////
9
!
10
   Module ScanningModule
11
   USE SMConstants, ONLY: RP
12
   USE SMScannerClass
13
   IMPLICIT NONE
14
   PRIVATE
15
   PUBLIC :: ScanForBreaks, ScanForBreaksIsOK, flaggingIsOK
16
!
17
!  ========
18
   CONTAINS
19
!  ========
20
!
21
!
22
!////////////////////////////////////////////////////////////////////////
23
!
24
   SUBROUTINE ScanForBreaks(connectionString, breaks, nSegments)
2✔
25
!
26
!     -----------------------------------------------------------------------
27
!     Compute the locations of the breaks in a curve as specified by the user
28
!     in the control file. Breaks are expressed in the form
29

30
!     connect = N1-N2, N3-N4 [,...]
31

32
!     e.g.
33
!     connect = 2-4, 6-9, 10-11
34
!
35
!     if there are four segments and connect = 2-3 then the breaks are
36
!     at the end of segments 1 and 3, and breaks = [0.0, 0.25, 0.75, 1.0],
37
!     skipping the breaks at 1/2 between segments 2 and 3. See
38
!     ScanForBreaksIsOK for examples
39
!  -----------------------------------------------------------------------
40
!
41
      IMPLICIT NONE
42
!
43
!     ---------
44
!     Arguments
45
!     ---------
46
!
47
      CHARACTER(LEN=*)           :: connectionString
48
      REAL(KIND=RP), ALLOCATABLE :: breaks(:)
49
      INTEGER                    :: nSegments
50
!
51
!     ---------------
52
!     Local variables
53
!     ---------------
54
!
55
      TYPE(SMScanner) :: scanner
2✔
56
      INTEGER         :: flagged(0:nSegments)
4✔
57
      INTEGER         :: flagCount
58
      LOGICAL         :: fail
59
      INTEGER         :: numberOfBreaks
60
      INTEGER         :: j, k
61
      REAL(KIND=RP) :: c
62

63
      flagged = 0
16✔
64
      CALL scanner % initWithString(connectionString,delims = ",-")
2✔
65
!
66
!     -------------------------------------------------------------
67
!     Flag the locations (with a 1) where breaks will NOT be placed
68
!     -------------------------------------------------------------
69
!
70
      CALL flagSegments(scanner, flagged, flagCount, 1, fail)
2✔
71
      IF ( fail )     THEN
2✔
NEW
72
         WRITE(0,*) "Scanning of the following connection lines failed with a syntax error"
×
NEW
73
         WRITE(0,*) TRIM(connectionString)
×
NEW
74
         RETURN
×
75
      END IF
76

77
      numberOfBreaks = nSegments - flagCount
2✔
78
      ALLOCATE(breaks(0:numberOfBreaks))
2✔
79
      breaks(0)              = 0.0_RP
2✔
80
      breaks(numberOfBreaks) = 1.0_RP
2✔
81

82
      k = 1
2✔
83
      c = 1.0_RP/REAL(nSegments,KIND=RP)
2✔
84
      DO j = 1, nSegments-1
12✔
85
         IF(flagged(j) == 1) CYCLE
10✔
86
         breaks(k) = j*c
6✔
87
         k = k + 1
8✔
88
      END DO
89

90

91
   END SUBROUTINE ScanForBreaks
4✔
92
!
93
!////////////////////////////////////////////////////////////////////////
94
!
95
   SUBROUTINE flagSegments(scanner, flagged, flagCount, flagOn, fail )
4✔
96
!
97
!  -----------------------------------------------------------------------
98
!  Using the scanner, scan its string for groups
99
!  in the form of start-stop, e.g. 4-6, separated by commas. Set
100
!  the entry in the array flagged to flagOn for each element of each group
101
!  For this procedure, the scanner must include "-" and "," as the delimiters.
102
!  -----------------------------------------------------------------------
103
!
104
      IMPLICIT NONE
105
!
106
!     ---------
107
!     Arguments
108
!     ---------
109
!
110
      TYPE(SMScanner) :: scanner
111
      INTEGER         :: flagged(0:)
112
      INTEGER         :: flagOn
113
      INTEGER         :: flagCount ! The total number of flagged segments
114
      LOGICAL         :: fail
115
!
116
!     ---------------
117
!     Local Variables
118
!     ---------------
119
!
120
      INTEGER          :: fSize
121
      INTEGER          :: j, k
122
      INTEGER          :: strt, stp
123

124
      fSize     = SIZE(flagged)
4✔
125
      fail      = .FALSE.
4✔
126
      flagCount = 0
4✔
127

128
      DO j = 1, fSize          ! Cannot be bigger than this
7✔
129
!
130
!        ------------------------
131
!        Get the start of a group
132
!        ------------------------
133
!
134
         strt = scanInt(scanner)
7✔
135
!
136
!        ---------------------------------------------------
137
!        The delimiter that stops this scan must be a "-" or
138
!        there is an error in the string
139
!        ---------------------------------------------------
140
!
141
         IF ( scanner % lastDelimiter() .NE. "-" )     THEN
7✔
NEW
142
            WRITE(0,*) "String start configuration error"
×
NEW
143
            fail = .TRUE.
×
144
            RETURN
7✔
145
         END IF
146

147
         stp = scanInt(scanner)
7✔
148
!
149
!        --------------------------------------------------------
150
!        After the integer is scanned, the next delimiter must be
151
!        either a comma or an end of string. It cannot be a -
152
!        --------------------------------------------------------
153
!
154
         IF ( scanner % lastDelimiter() .EQ. "-")     THEN
7✔
NEW
155
            WRITE(0,*) "String stop configuration error"
×
NEW
156
            fail = .TRUE.
×
157
            RETURN
7✔
158
         END IF
159
!
160
!        --------------------------------------------------------
161
!        At the end of the string, we don't flag the last segment
162
!        --------------------------------------------------------
163
!
164
         DO k = strt, stp-1
18✔
165
            flagged(k) = flagOn
11✔
166
            flagCount  = flagCount + 1
18✔
167
         END DO
168
!
169
!        -----------------------------------------------
170
!        We're done when we get to the end of the string
171
!        -----------------------------------------------
172
!
173
         IF (scanner % isAtEnd() )     EXIT
7✔
174
      END DO
175

176
   END SUBROUTINE flagSegments
177

178
!
179
!////////////////////////////////////////////////////////////////////////
180
!
181
   LOGICAL FUNCTION flagString(str, flagged, flagCount)
2✔
182
      IMPLICIT NONE
183
!
184
!     ---------
185
!     Arguments
186
!     ---------
187
!
188
      CHARACTER(LEN=*) :: str
189
      INTEGER          :: flagged(0:)
190
      INTEGER          :: flagCount
191
!
192
!     ---------------
193
!     Local variables
194
!     ---------------
195
!
196
      TYPE(SMScanner) :: scanner
2✔
197
      LOGICAL         :: fail
198

199
      flagged = 0
20✔
200
      CALL scanner % initWithString(str,delims = ",-")
2✔
201

202
      CALL flagSegments(scanner, flagged, flagCount, 1, fail)
2✔
203

204
      flagString = fail
2✔
205

206
   END FUNCTION flagString
4✔
207
!
208
!////////////////////////////////////////////////////////////////////////
209
!
210
   LOGICAL FUNCTION flaggingIsOK()
1✔
211
      IMPLICIT NONE
212
      LOGICAL           :: fail
213
      CHARACTER(LEN=16) :: str
214
      INTEGER           :: flagged(0:8)
215
      INTEGER           :: flagCount
216
      INTEGER           :: flagged1(0:8), flagged2(0:8)
217

218
      flaggingIsOK = .TRUE.
1✔
219
!
220
!     -----
221
!     Try 1
222
!     -----
223
!
224
      str = "2-3,5-8"
1✔
225
      flagged1 = [0,0,1,0,0,1,1,1,0]
1✔
226
      fail     = flagString(str, flagged, flagCount)
1✔
227
      flaggingIsOK = .NOT.fail .AND. flaggingIsOK
1✔
228
      flaggingIsOK = MAXVAL(flagged - flagged1) == 0 .AND. flaggingIsOK
10✔
229
!
230
!     -----
231
!     Try 2
232
!     -----
233
!
234
      str = "1-3,6-7"
1✔
235
      flagged2 = [0,1,1,0,0,0,1,0,0]
1✔
236
      fail = flagString(str, flagged, flagCount)
1✔
237
      flaggingIsOK = .NOT.fail .AND. flaggingIsOK
1✔
238
      flaggingIsOK = MAXVAL(flagged - flagged2) == 0 .AND. flaggingIsOK
10✔
239

240
   END FUNCTION flaggingIsOK
1✔
241
!
242
!////////////////////////////////////////////////////////////////////////
243
!
244
   LOGICAL FUNCTION ScanForBreaksIsOK()
1✔
245
      IMPLICIT NONE
246
      CHARACTER(LEN=16) :: testString1 = "2-3"
247
      CHARACTER(LEN=16) :: testString2 = "1-2,4-6"
248
      REAL(KIND=RP), ALLOCATABLE :: breaks(:)
1✔
249
      REAL(KIND=RP)              :: b1(0:3) = [0.0_RP, 0.25_RP, 0.75_RP, 1.0_RP]
250
      REAL(KIND=RP)              :: b2(0:5) = [0.0_RP, 0.25_RP, 0.375_RP, 0.75_RP, 0.875_RP, 1.0_RP]
251
      INTEGER                    :: nSegments = 4
252

253
      ScanForBreaksIsOK = .TRUE.
1✔
254

255
      CALL ScanForBreaks(testString1, breaks, nSegments )
1✔
256
      ScanForBreaksIsOK = MAXVAL(b1 - breaks) == 0.0_RP
5✔
257
      DEALLOCATE(breaks)
1✔
258

259
      CALL ScanForBreaks(testString2, breaks, nSegments*2 )
1✔
260
      ScanForBreaksIsOK = ScanForBreaksIsOK .AND. MAXVAL(b2 - breaks) == 0.0_RP
7✔
261

262
   END FUNCTION ScanForBreaksIsOK
1✔
263

264

265
   END Module ScanningModule
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc