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

(feat) Added abstract class for interpolators

parent 26bac6aa
No related branches found
No related tags found
1 merge request!1BLASTER v1.0
Pipeline #51033 passed
......@@ -70,7 +70,7 @@ class SolversInterface:
else:
raise RuntimeError('Incorrect interpolator specified in config.')
self.interpolator = interp(self.cfg, self.getnDim())
self.interpolator = interp(self.getnDim(), **self.cfg)
# Initialize transfer quantities
self.deltaStarExt = [[np.zeros(0) for iReg in range(3)]\
......
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2024 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.
# Abstract interpolator class
# Paul Dechamps
class Interpolator:
"""
Abstract interpolator class
Attributes:
----------
ndim : int
Number of dimensions (must be 2 or 3).
"""
def __init__(self, _ndim):
"""
Initialize the Interpolator.
Parameters:
----------
ndim : int
Number of dimensions (must be 2 or 3).
"""
if _ndim != 2 and _ndim != 3:
raise ValueError('Number of dimensions must be 2 or 3 but {} was given'.format(ndim))
self.ndim = _ndim
def inviscidToViscous(self, iDict, vDict):
"""
Interpolate data from the inviscid mesh to the viscous mesh.
Parameters:
----------
iDict : list
List blDataStructure objects for the inviscid part.
vDict : list
List blDataStructure objects for the viscous part.
"""
raise NotImplementedError('inviscidToViscous method not implemented')
def viscousToInviscid(self, iDict, vDict):
"""
Interpolate data from the viscous mesh to the inviscid mesh.
Parameters:
----------
iDict : list
List blDataStructure objects for the inviscid part.
vDict : list
List blDataStructure objects for the viscous part.
"""
raise NotImplementedError('viscousToInviscid method not implemented')
import numpy as np
class MatchingInterpolator:
# Copyright 2024 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.
# Matching interpolator class
# Paul Dechamps
from blast.interfaces.interpolators.blInterpolator import Interpolator
class MatchingInterpolator(Interpolator):
"""
Matching Interpolator for inviscid and viscous data.
Attributes:
----------
cfg : dict
Configuration dictionary.
nDim : int
Number of dimensions.
_sections : list
List of boundary layers sections.
"""
def __init__(self, cfg, ndim):
def __init__(self, ndim, **kwargs):
"""
Initialize the MatchingInterpolator.
Parameters:
----------
_cfg : dict
Configuration dictionary.
_nDim : int
ndim : int
Number of dimensions.
kwargs : dict
Optional arguments.
Optional arguments:
-------------------
sections : list
List of sections for 3D cases.
"""
self._cfg = cfg
self._ndim = ndim
super().__init__(ndim)
self._sections = kwargs.get('sections')
if self.ndim == 2 and len(self._sections) > 1:
raise RuntimeError('Multiple sections are not supported in 2D')
def inviscidToViscous(self, iDict, vDict):
"""
......@@ -35,11 +59,11 @@ class MatchingInterpolator:
vDict : dict
Viscous data dictionary.
"""
if self._ndim == 2:
if self.ndim == 2:
for iReg in range(len(iDict)):
vDict[0][iReg].updateVars(iDict[iReg].V, iDict[iReg].M, iDict[iReg].Rho)
elif self._ndim == 3:
for iSec, ysec in enumerate(self._cfg['sections']):
elif self.ndim == 3:
for iSec, ysec in enumerate(self._sections):
for iReg in range(2):
print(iDict[iReg].nodesCoord[iDict[iReg].nodesCoord[:,1] == ysec])
print(iDict[iReg].V[iDict[iReg].nodesCoord[:,1] == ysec])
......@@ -56,8 +80,8 @@ class MatchingInterpolator:
vDict : dict
Viscous data dictionary.
"""
if self._ndim == 2:
if self.ndim == 2:
for iReg in range(2):
iDict[iReg].blowingVel = vDict[0][iReg].blowingVel
else:
raise RuntimeError('Incorrect number of dimensions', self._ndim)
\ No newline at end of file
raise RuntimeError('Incorrect number of dimensions', self.ndim)
\ No newline at end of file
# Copyright 2024 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.
# RBF interpolator class
# Paul Dechamps
from blast.interfaces.interpolators.blInterpolator import Interpolator
import numpy as np
from scipy.interpolate import RBFInterpolator
class RbfInterpolator:
class RbfInterpolator(Interpolator):
"""
Radial Basis Function (RBF) Interpolator for inviscid and viscous data.
Attributes:
----------
_cfg : dict
Configuration dictionary.
_ndim : int
Number of dimensions (2 or 3).
_neighbors : int
Number of neighbors to use for interpolation.
_rbftype : str
Type of RBF kernel to use.
_smoothing : float
Smoothing factor.
_degree : int
Degree of the polynomial kernel.
_sym : list
List of symmetry planes.
"""
def __init__(self, cfg, ndim):
def __init__(self, ndim, **kwargs):
"""
Initialize the RbfInterpolator.
Parameters:
----------
cfg : dict
Configuration dictionary.
ndim : int
Number of dimensions (must be 2 or 3).
kwargs : dict
Optional arguments.
Optional arguments:
-------------------
nneighbors : int
Number of neighbors to use for interpolation. Default is 10.
rbftype : str
Type of RBF kernel to use. Default is 'linear'.
smoothing : float
Smoothing factor. Default is 0.0.
degree : int
Degree of the polynomial kernel. Default is 0.
"""
self._cfg = cfg
if ndim != 2 and ndim != 3:
raise ValueError('Number of dimensions must be 2 or 3 but {} was given'.format(ndim))
self._ndim = ndim
super().__init__(ndim)
self._neighbors = kwargs.get('neighbors', 10)
self._rbftype = kwargs.get('rbftype', 'linear')
self._smoothing = kwargs.get('smoothing', 0.0)
self._degree = kwargs.get('degree', 0)
self._sym = kwargs.get('Sym', [])
def inviscidToViscous(self, iDict, vDict):
"""
......@@ -48,9 +84,9 @@ class RbfInterpolator:
M = np.zeros(reg.nodesCoord.shape[0])
rho = np.zeros(reg.nodesCoord.shape[0])
for iDim in range(3):
v[:,iDim] = self.__rbfToSection(iDict[iReg].nodesCoord[:,:(self._ndim if iDict[iReg].name == 'iWing' else 1)], iDict[iReg].V[:,iDim], reg.nodesCoord[:,:(self._ndim if 'vAirfoil' in reg.name else 1)])
M = self.__rbfToSection(iDict[iReg].nodesCoord[:,:(self._ndim if iDict[iReg].name == 'iWing' else 1)], iDict[iReg].M, reg.nodesCoord[:,:(self._ndim if 'vAirfoil' in reg.name else 1)])
rho = self.__rbfToSection(iDict[iReg].nodesCoord[:,:(self._ndim if iDict[iReg].name == 'iWing' else 1)], iDict[iReg].Rho, reg.nodesCoord[:,:(self._ndim if 'vAirfoil' in reg.name else 1)])
v[:,iDim] = self.__rbfToSection(iDict[iReg].nodesCoord[:,:(self.ndim if iDict[iReg].name == 'iWing' else 1)], iDict[iReg].V[:,iDim], reg.nodesCoord[:,:(self.ndim if 'vAirfoil' in reg.name else 1)])
M = self.__rbfToSection(iDict[iReg].nodesCoord[:,:(self.ndim if iDict[iReg].name == 'iWing' else 1)], iDict[iReg].M, reg.nodesCoord[:,:(self.ndim if 'vAirfoil' in reg.name else 1)])
rho = self.__rbfToSection(iDict[iReg].nodesCoord[:,:(self.ndim if iDict[iReg].name == 'iWing' else 1)], iDict[iReg].Rho, reg.nodesCoord[:,:(self.ndim if 'vAirfoil' in reg.name else 1)])
vDict[iSec][iReg].updateVars(v, M, rho)
def viscousToInviscid(self, iDict, vDict):
......@@ -64,22 +100,21 @@ class RbfInterpolator:
vDict : dict
Viscous data dictionary.
"""
if self._ndim == 2:
if self.ndim == 2:
for iReg, reg in enumerate(iDict):
iDict[iReg].blowingVel = self.__rbfToSection(vDict[0][iReg].elemsCoordTr[:,:(self._ndim-1 if 'vAirfoil' in reg.name else 1)], vDict[0][iReg].blowingVel, reg.elemsCoordTr[:,:(self._ndim-1 if reg.name == 'iWing' else 1)])
elif self._ndim == 3:
iDict[iReg].blowingVel = self.__rbfToSection(vDict[0][iReg].elemsCoordTr[:,:(self.ndim-1 if 'vAirfoil' in reg.name else 1)], vDict[0][iReg].blowingVel, reg.elemsCoordTr[:,:(self.ndim-1 if reg.name == 'iWing' else 1)])
elif self.ndim == 3:
for iReg, reg in enumerate(iDict):
viscElemsCoord = np.zeros((0,3))
viscBlowing = np.zeros(0)
for iSec, sec in enumerate(vDict):
viscElemsCoord = np.row_stack((viscElemsCoord, sec[iReg].elemsCoord[:,:3]))
viscBlowing = np.concatenate((viscBlowing, sec[iReg].blowingVel))
if 'Sym' in self._cfg:
for s in self._cfg['Sym']:
dummy = viscElemsCoord.copy()
dummy[:,1] = (dummy[:,1] - s)*(-1) + s
viscElemsCoord = np.row_stack((viscElemsCoord, dummy))
viscBlowing = np.concatenate((viscBlowing, viscBlowing))
for s in self._sym:
dummy = viscElemsCoord.copy()
dummy[:,1] = (dummy[:,1] - s)*(-1) + s
viscElemsCoord = np.row_stack((viscElemsCoord, dummy))
viscBlowing = np.concatenate((viscBlowing, viscBlowing))
reg.blowingVel = self.__rbfToSection(viscElemsCoord, viscBlowing, reg.elemsCoord[:,:3])
def __rbfToSection(self, x, var, xs):
......@@ -103,5 +138,5 @@ class RbfInterpolator:
if np.all(var == var[0]):
varOut = RBFInterpolator(x, var, neighbors=1, kernel='linear', smoothing=0.0, degree=0)(xs)
else:
varOut = RBFInterpolator(x, var, neighbors=self._cfg['neighbors'], kernel=self._cfg['rbftype'], smoothing=self._cfg['smoothing'], degree=self._cfg['degree'])(xs)
varOut = RBFInterpolator(x, var, neighbors=self._neighbors, kernel=self._rbftype, smoothing=self._smoothing, degree=self._degree)(xs)
return varOut
\ No newline at end of file
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