Skip to content
Snippets Groups Projects
Verified Commit bc2c3362 authored by Paul Dechamps's avatar Paul Dechamps :speech_balloon:
Browse files

(test) Added Agard wing test case

parent 627ec220
No related branches found
No related tags found
1 merge request!1BLASTER v1.0
Pipeline #19875 passed
/* AGARD 445 wing */
// Initially generated by unsRgridWingGen.m
// Parameters
// domain and mesh
DefineConstant[ nSpan = { 20, Name "Spanwise number of elements" } ];
DefineConstant[ nLe = { 5, Name "LE chordwise number of elements" } ];
DefineConstant[ nTe = { 5, Name "TE chordwise number of elements" } ];
DefineConstant[ nMid = { 10, Name "Mid chordwise number of elements" } ];
DefineConstant[ nWake = { 15, Name "Wake number of elements" } ];
DefineConstant[ progSpan = { 1, Name "Spanwise progression" } ];
DefineConstant[ progLe = { 1, Name "LE progression" } ];
DefineConstant[ progTe = { 1, Name "TE progression" } ];
DefineConstant[ progMid = { 1, Name "Mid progression" } ];
DefineConstant[ progWake = { 1.0, Name "Wake progression" } ];
DefineConstant[ xO = { -3, Name "Box origin (x)" } ];
DefineConstant[ zO = { -3, Name "Box origin (z)" } ];
DefineConstant[ xL = { 7, Name "Box length" } ];
DefineConstant[ yL = { 3, Name "Box width" } ];
DefineConstant[ zL = { 6, Name "Box height" } ];
//// GEOMETRY
/// Points
// Airfoil 1: agard445, 51 points
Point(1) = {0.559000,0.000000,0.000000};
Point(2) = {0.531050,0.000000,0.001398};
Point(3) = {0.503100,0.000000,0.002739};
Point(4) = {0.475150,0.000000,0.004075};
Point(5) = {0.447200,0.000000,0.005406};
Point(6) = {0.419250,0.000000,0.006680};
Point(7) = {0.391300,0.000000,0.007837};
Point(8) = {0.363350,0.000000,0.008866};
Point(9) = {0.335400,0.000000,0.009743};
Point(10) = {0.307450,0.000000,0.010442};
Point(11) = {0.279500,0.000000,0.010923};
Point(12) = {0.251550,0.000000,0.011158};
Point(13) = {0.223600,0.000000,0.011163};
Point(14) = {0.195650,0.000000,0.010968};
Point(15) = {0.167700,0.000000,0.010576};
Point(16) = {0.139750,0.000000,0.009995};
Point(17) = {0.111800,0.000000,0.009196};
Point(18) = {0.083850,0.000000,0.008156};
Point(19) = {0.055900,0.000000,0.006781};
Point(20) = {0.041925,0.000000,0.005920};
Point(21) = {0.027950,0.000000,0.004891};
Point(22) = {0.013975,0.000000,0.003617};
Point(23) = {0.006988,0.000000,0.002622};
Point(24) = {0.004193,0.000000,0.002057};
Point(25) = {0.002795,0.000000,0.001699};
Point(26) = {0.000000,0.000000,0.000000};
Point(27) = {0.002795,0.000000,-0.001699};
Point(28) = {0.004193,0.000000,-0.002057};
Point(29) = {0.006988,0.000000,-0.002622};
Point(30) = {0.013975,0.000000,-0.003617};
Point(31) = {0.027950,0.000000,-0.004891};
Point(32) = {0.041925,0.000000,-0.005920};
Point(33) = {0.055900,0.000000,-0.006781};
Point(34) = {0.083850,0.000000,-0.008156};
Point(35) = {0.111800,0.000000,-0.009196};
Point(36) = {0.139750,0.000000,-0.009995};
Point(37) = {0.167700,0.000000,-0.010576};
Point(38) = {0.195650,0.000000,-0.010968};
Point(39) = {0.223600,0.000000,-0.011163};
Point(40) = {0.251550,0.000000,-0.011158};
Point(41) = {0.279500,0.000000,-0.010923};
Point(42) = {0.307450,0.000000,-0.010442};
Point(43) = {0.335400,0.000000,-0.009743};
Point(44) = {0.363350,0.000000,-0.008866};
Point(45) = {0.391300,0.000000,-0.007837};
Point(46) = {0.419250,0.000000,-0.006680};
Point(47) = {0.447200,0.000000,-0.005406};
Point(48) = {0.475150,0.000000,-0.004075};
Point(49) = {0.503100,0.000000,-0.002739};
Point(50) = {0.531050,0.000000,-0.001398};
// Airfoil 2: agard445, 51 points
Point(52) = {1.178128,0.762000,0.000000};
Point(53) = {1.159709,0.762000,0.000921};
Point(54) = {1.141290,0.762000,0.001805};
Point(55) = {1.122870,0.762000,0.002685};
Point(56) = {1.104451,0.762000,0.003562};
Point(57) = {1.086032,0.762000,0.004402};
Point(58) = {1.067613,0.762000,0.005165};
Point(59) = {1.049194,0.762000,0.005843};
Point(60) = {1.030775,0.762000,0.006421};
Point(61) = {1.012356,0.762000,0.006881};
Point(62) = {0.993937,0.762000,0.007198};
Point(63) = {0.975518,0.762000,0.007353};
Point(64) = {0.957099,0.762000,0.007357};
Point(65) = {0.938680,0.762000,0.007228};
Point(66) = {0.920261,0.762000,0.006970};
Point(67) = {0.901842,0.762000,0.006587};
Point(68) = {0.883423,0.762000,0.006060};
Point(69) = {0.865004,0.762000,0.005375};
Point(70) = {0.846585,0.762000,0.004468};
Point(71) = {0.837375,0.762000,0.003901};
Point(72) = {0.828166,0.762000,0.003223};
Point(73) = {0.818956,0.762000,0.002383};
Point(74) = {0.814351,0.762000,0.001728};
Point(75) = {0.812509,0.762000,0.001356};
Point(76) = {0.811589,0.762000,0.001120};
Point(77) = {0.809747,0.762000,0.000000};
Point(78) = {0.811589,0.762000,-0.001120};
Point(79) = {0.812509,0.762000,-0.001356};
Point(80) = {0.814351,0.762000,-0.001728};
Point(81) = {0.818956,0.762000,-0.002383};
Point(82) = {0.828166,0.762000,-0.003223};
Point(83) = {0.837375,0.762000,-0.003901};
Point(84) = {0.846585,0.762000,-0.004468};
Point(85) = {0.865004,0.762000,-0.005375};
Point(86) = {0.883423,0.762000,-0.006060};
Point(87) = {0.901842,0.762000,-0.006587};
Point(88) = {0.920261,0.762000,-0.006970};
Point(89) = {0.938680,0.762000,-0.007228};
Point(90) = {0.957099,0.762000,-0.007357};
Point(91) = {0.975518,0.762000,-0.007353};
Point(92) = {0.993937,0.762000,-0.007198};
Point(93) = {1.012356,0.762000,-0.006881};
Point(94) = {1.030775,0.762000,-0.006421};
Point(95) = {1.049194,0.762000,-0.005843};
Point(96) = {1.067613,0.762000,-0.005165};
Point(97) = {1.086032,0.762000,-0.004402};
Point(98) = {1.104451,0.762000,-0.003562};
Point(99) = {1.122870,0.762000,-0.002685};
Point(100) = {1.141290,0.762000,-0.001805};
Point(101) = {1.159709,0.762000,-0.000921};
// Midplane:
Point(5351) = {xO+xL,0.000000,0.000000};
Point(5352) = {xO+xL,0.762000,0.000000};
/// Lines
// Airfoil 1:
Spline(1) = {1,2,3};
Spline(2) = {3,4,5,6,7,8,9,10,11,12,13,14,15};
Spline(3) = {15,16,17,18,19,20,21,22,23,24,25,26};
Spline(4) = {26,27,28,29,30,31,32,33,34,35,36,37};
Spline(5) = {37,38,39,40,41,42,43,44,45,46,47,48,49};
Spline(6) = {49,50,1};
// Airfoil 2:
Spline(7) = {52,53,54};
Spline(8) = {54,55,56,57,58,59,60,61,62,63,64,65,66};
Spline(9) = {66,67,68,69,70,71,72,73,74,75,76,77};
Spline(10) = {77,78,79,80,81,82,83,84,85,86,87,88};
Spline(11) = {88,89,90,91,92,93,94,95,96,97,98,99,100};
Spline(12) = {100,101,52};
// Airfoil 1 to airfoil 2:
Line(61) = {1,52};
Line(62) = {3,54};
Line(63) = {15,66};
Line(64) = {26,77};
Line(65) = {37,88};
Line(66) = {49,100};
// Midplane:
Line(131) = {5351,5352};
// Wing to midplane:
Line(161) = {1,5351};
Line(162) = {52,5352};
/// Line loops & Surfaces
// Wing 1:
Line Loop(11) = {1,62,-7,-61};
Line Loop(12) = {2,63,-8,-62};
Line Loop(13) = {3,64,-9,-63};
Line Loop(14) = {4,65,-10,-64};
Line Loop(15) = {5,66,-11,-65};
Line Loop(16) = {6,61,-12,-66};
Surface(11) = {-11};
Surface(12) = {-12};
Surface(13) = {-13};
Surface(14) = {-14};
Surface(15) = {-15};
Surface(16) = {-16};
// Wake:
Line Loop(81) = {161,131,-162,-61};
Surface(81) = {81};
/// Surface loops & Volumes
//// MESHING ALGORITHM
//// PHYSICAL GROUPS
// Trailing edge and wake tip
Physical Line("wakeTip") = {162};
Physical Line("te") = {61};
// Wing:
Physical Surface("wing") = {11,12,13};
Physical Surface("wing_") = {14,15,16};
// Wake:
Physical Surface("wake") = {81};
Coherence;
Transfinite Curve {161, 162} = nWake Using Progression progWake;
Transfinite Curve {131, 61, 62, 66, 63, 65, 64} = nSpan Using Progression progSpan;
Transfinite Curve {-3, 4, -9, 10} = nLe Using Progression progLe;
Transfinite Curve {7, -12, 1, -6} = nTe Using Progression progTe;
Transfinite Curve {2, 5, 8, 11} = nMid Using Progression progMid;
Transfinite Surface {81};
Transfinite Surface {12};
Transfinite Surface {15};
Transfinite Surface {13};
Transfinite Surface {14};
Transfinite Surface {11};
Transfinite Surface {16};
Recombine Surface {81};
Recombine Surface {12};
Recombine Surface {15};
Recombine Surface {13};
Recombine Surface {14};
Recombine Surface {11};
Recombine Surface {16};
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2022 University of Liège
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# @author Paul Dechamps
# @date 2022
# Test the blast implementation. The test case is a compressible attached transitional flow.
# Tested functionalities;
# - Time integration.
# - Two time-marching techniques (agressive and safe).
# - Transition routines.
# - Forced transition.
# - Compressible flow routines.
# - Laminar and turbulent flow.
#
# Untested functionalities.
# - Separation routines.
# - Multiple failure case at one iteration.
# - Response to unconverged inviscid solver.
# Imports.
import blast.utils as viscUtils
import numpy as np
import os.path
from fwk.wutils import parseargs
import fwk
from fwk.testing import *
from fwk.coloring import ccolors
import math
def cfgInviscid(nthrds, verb):
# Parameters
return {
# Options
'scenario' : 'aerodynamic',
'task' : 'analysis',
'Threads' : nthrds, # number of threads
'Verb' : verb, # verbosity
# Model (geometry or mesh)
'File' : os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + '/modules/dartflo/dart/models/agard445.geo', # Input file containing the model
'Pars' : {'xL': 7., 'yL': 3., 'zL': 6., 'xO': -3, 'zO': -3, 'msLeRt': 0.0028, 'msTeRt': 0.0056, 'msLeTp': 0.0018, 'msTeTp': 0.0036, 'msF': 1.0}, # parameters for input file model
'Dim' : 3, # problem dimension
'Format' : 'vtk', # save format (vtk or gmsh)
# Markers
'Fluid' : 'field', # name of physical group containing the fluid
'Farfield' : ['upstream', 'farfield', 'downstream'], # LIST of names of physical groups containing the farfield boundaries (upstream/downstream should be first/last element)
'Wings' : ['wing'], # LIST of names of physical groups containing the lifting surface boundary
'Wakes' : ['wake'], # LIST of names of physical group containing the wake
'WakeTips' : ['wakeTip'], # LIST of names of physical group containing the edge of the wake
'Tes' : ['te'], # LIST of names of physical group containing the trailing edge
'dbc' : True,
'Upstream' : 'upstream',
# Freestream
'M_inf' : 0.954, # freestream Mach number
'AoA' : 1, # freestream angle of attack
# Geometry
'S_ref' : 0.35, # reference surface length
'c_ref' : 0.47, # reference chord length
'x_ref' : 0.0, # reference point for moment computation (x)
'y_ref' : 0.0, # reference point for moment computation (y)
'z_ref' : 0.0, # reference point for moment computation (z)
# Numerical
'LSolver' : 'GMRES', # inner solver (Pardiso, MUMPS or GMRES)
'G_fill' : 2, # fill-in factor for GMRES preconditioner
'G_tol' : 1e-5, # tolerance for GMRES
'G_restart' : 50, # restart for GMRES
'Rel_tol' : 1e-6, # relative tolerance on solver residual
'Abs_tol' : 1e-8, # absolute tolerance on solver residual
'Max_it' : 50 # solver maximum number of iterations
}
def cfgBlast(verb):
return {
'Re' : 6.7e6, # Freestream Reynolds number
'Minf' : 0.954, # Freestream Mach number (used for the computation of the time step only)
'CFL0' : 1, # Inital CFL number of the calculation
'sections' : np.linspace(0.026, 0.7, 15),
'writeSections': np.linspace(0.01, 0.76, 15),
'Sym':[0.],
'span': 0.762,
'interpolator': 'Rbf',
'rbftype': 'linear',
'smoothing': 1e-8,
'degree': 0,
'neighbors': 10,
'saveTag': 5,
'Verb': verb, # Verbosity level of the solver
'couplIter': 100, # Maximum number of iterations
'couplTol' : 1e-3, # Tolerance of the VII methodology
'iterPrint': 1, # int, number of iterations between outputs
'resetInv' : True, # bool, flag to reset the inviscid calculation at every iteration.
'xtrF' : [0., 0.], # Forced transition location
'nDim' : 3
}
def main():
# Timer.
tms = fwk.Timers()
tms['total'].start()
args = parseargs()
icfg = cfgInviscid(args.k, args.verb)
vcfg = cfgBlast(args.verb)
parsViscous = {'nLe': 15, 'nMid': 30, 'nTe': 7, 'nSpan': 60, 'nWake': 30,
'progLe': 1.07, 'progMid': 1.0, 'progTe': 1.0, 'progSpan': 1.0, 'progWake': 1.15}
vMsh = viscUtils.mesh(os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '/models/dart/agard445_visc.geo', parsViscous)
vcfg['vMsh'] = vMsh
tms['pre'].start()
coupler, iSolverAPI, vSolver = viscUtils.initBlast(icfg, vcfg)
tms['pre'].stop()
print(ccolors.ANSI_BLUE + 'PySolving...' + ccolors.ANSI_RESET)
tms['solver'].start()
aeroCoeffs = coupler.run()
tms['solver'].stop()
# Display results.
print(ccolors.ANSI_BLUE + 'PyRes...' + ccolors.ANSI_RESET)
print(' Re M alpha Cl Cd Cdp Cdf Cm')
print('{0:6.1f}e6 {1:8.2f} {2:8.1f} {3:8.4f} {4:8.4f} {5:8.4f} {6:8.4f} {7:8.4f}'.format(vcfg['Re']/1e6, iSolverAPI.getMinf(), iSolverAPI.getAoA()*180/math.pi, iSolverAPI.getCl(), vSolver.Cdt, vSolver.Cdp, vSolver.Cdf, iSolverAPI.getCm()))
# Write results to file.
vSolution = viscUtils.getSolution(vSolver)
# Write results to file.
for iSec in range(len(iSolverAPI.cfg['EffSections'])):
vSolution = viscUtils.getSolution(vSolver, iSec)
viscUtils.write(vSolution, vSolver.getRe(), sfx='slice'+str(iSec))
vSolution['Cdt_int'] = vSolver.Cdf + iSolverAPI.getCd()
# Save pressure coefficient
iSolverAPI.save(sfx='_viscous')
tms['total'].stop()
print(ccolors.ANSI_BLUE + 'PyTiming...' + ccolors.ANSI_RESET)
print('CPU statistics')
print(tms)
print('SOLVERS statistics')
print(coupler.tms)
# Test solution
print(ccolors.ANSI_BLUE + 'PyTesting...' + ccolors.ANSI_RESET)
tests = CTests()
tests.add(CTest('Cl', iSolverAPI.getCl(), 0.069, 5e-2))
tests.add(CTest('Cd wake', vSolution['Cdt_int'], 0.00498, 1e-3, forceabs=True))
tests.add(CTest('Iterations', len(aeroCoeffs), 8, 0, forceabs=True))
tests.run()
# eof
print('')
if __name__ == "__main__":
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment