Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
iBatistic committed Aug 2, 2024
1 parent dbadba4 commit 17b9500
Show file tree
Hide file tree
Showing 430 changed files with 139,268 additions and 128 deletions.
105 changes: 53 additions & 52 deletions applications/solvers/pUelasticSolidFoam.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
from src.foam.field.volField.volScalarField import volScalarField
from src.finiteVolume.fvMatrices.fvm.fvm import fvm
from src.finiteVolume.fvMatrices.fvc.fvc import fvc
from src.finiteVolume.fvMatrices.fvc.operators.interpolate import interpolate

from src.finiteVolume.fvMatrices.fvc.operators import *

# Execution start time, used to measured elapsed clock time
exec_start_time = timeModule.perf_counter()
Expand All @@ -45,33 +44,20 @@
# Initialise displacement vector field U, N is interpolation order
U = volVectorField("U", mesh, readVectorField("U"), N)

volOverD = volVectorField("volOverD", mesh, readVectorField("volOverD"), N)

# Initialise pressure scalar field p
p = volScalarField("p", mesh, readScalarField("p"), N)

# Initialise pressure correction scalar field pCorr
#pCorr = volScalarField("p", mesh, readScalarField("pCorr"), N)
pCorr = volScalarField("pCorr", mesh, readScalarField("pCorr"), N)

# Read mechanichalProperties dict to get first and second Lame parameters
mu, lam = readMechanicalProperties()

# Move to SIMPLE or to be consistent with OF calculate here.
# MAybe add fvc.interpolate functions?
def predictFaceDisplacement(U, p, pressureGrad, D):
'''
Correct face displacement according to Rhie-chow interpolation.
Return field is corrected displacement value for each Gauss point
'''

# Ustar = interpolate.vectorInterpolate(U)
# rAU = interpolate.vectorInterpolate(1/D)
# pressureGrad = interpolate.vectorInterpolate()
# interpolate.
# pass


while (solControl.loop()):

print(f'Time = {solControl.time()} \n')
print(f'\nTime = {solControl.time()} \n')

# Assemble the Laplacian, LaplacianTranspose and body force
laplacian = fvm.construct(U, 'Laplacian', mu)
Expand All @@ -87,46 +73,61 @@ def predictFaceDisplacement(U, p, pressureGrad, D):
# Solve momentum matrix
momentumMatrix.solve()

# Velocity interpolated to face Gauss points
UStar = interpolate.interpolate(U)
# Displacement interpolated to face Gauss points
UStar = interpolate.cellToFace(U)

# Inverse of momentum matrix diagonal (tensor coefficient) multiplied with
# cell volume
volOverDiag = momentumMatrix.volOverD()

# Interpolate volOverDiag to face Gauss points
pGamma = interpolate.diagToFace(volOverDiag, volOverD)

# Face Gauss points pressure gradient using interpolation coefficients
# mu and U are used for pressureTraction boundaries to get pressure from
# constitutive relation
pressureGrad = interpolateGrad.cellToFace(p, mu, U)
barPressureGrad = interpolateCellGrad.cellToFace(p, mu, U)

# Inverted momentum matrix diagonal coefficients multiplied with cell volume
#volOverDiag = momentumMatrix.volOverD()
#pGamma = interpolate.scalarInterpolate(volOverDiag)
# Rhie-Chow correction for interpolated velocity
UHat = UStar

#divU = fvc.construct(UStar, 'div')
#laplacianPressureCorr = fvm.construct(pCorr, 'pressureCorrLaplacian', pGamma)
for faceI in range(mesh.nFaces):
for gpI in range(U.Ng):
UHat[faceI][gpI] += pGamma[faceI][gpI] @ (barPressureGrad[faceI][gpI] - pressureGrad[faceI][gpI] )

#pressureCorrMatrix = divU - laplacianPressureCorr
divU = fvc.construct(UHat, 'div', cellPsi=U)
laplacianPressureCorr = fvm.construct(pCorr, 'pCorrLaplacian', pGamma)

pressureCorrMatrix = laplacianPressureCorr + divU

# Solve pressure correction matrix
#pressureCorrMatrix.solve()

# Correct pressure and displacement fields
#p = p + pCorr
#gradPCorr = fvc.construct(pcorrGrad--)
#U = UStar - volOverDiag@gradPCorr


# momentumMatrix._A.convert('dense')
# test= momentumMatrix._A.getDenseArray()
# np.set_printoptions(precision=2, suppress=True)
# wr= [test[i:i + 1].tolist() for i in range(0, len(test), 1)]
#
# for item in wr:
# print(np.array(item))
# # Displacement correction using Rhie-Chow interpolation
# D = momentumMatrix.A
# UHat = predictFaceDisplacement(U, p, pressureGrad, D)
#
# # Pressure equation
# divU = fvm.construct(UHat, 'div')
# pressureLaplacian = fvm.construct(pCorr, 'Laplacian', D)
#
pressureCorrMatrix.solve()

# Tu sam dodao negativni predznak, vidi zasto je bio potreban!
for I in range(len(pCorr._cellValues)):
pCorr._cellValues[I] = np.array(pCorr._cellValues[I])*0.05

# Correct pressure field
print("a sto sa rubnim uvjetima nakon sto podrelaksiram??")
p.addCorrection(pCorr, relaxation=1)

# Correct displacement field
pCorrCellGrad = fvc.construct(pCorr, 'grad')._source.getArray()
pCorrCellGrad = [pCorrCellGrad[i:i + 3].tolist() for i in range(0, len(pCorrCellGrad), 3)]

for cellI, pC in enumerate(pCorrCellGrad):
U._cellValues[cellI] -= volOverDiag[cellI] @ pC

# Write results
U.write(solControl.time())
p.write(solControl.time())
pCorr.write(solControl.time())

# Check convergence and stop iterating if convergence is meet
#break

print(f'Execution time = '
f'{timeModule.perf_counter() - exec_start_time:.2f} s \n')
print(f'\nExecution time = '
f'{timeModule.perf_counter() - exec_start_time:.2f} s \n')

print('End\n')
43 changes: 37 additions & 6 deletions src/finiteVolume/fvMatrices/fvMatrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
__author__ = 'Ivan Batistić & Philip Cardiff'
__email__ = 'ibatistic@fsb.hr, philip.cardiff@ucd.ie'

import numpy as np
from petsc4py import PETSc
from src.foam.decorators import timed

Expand All @@ -21,15 +22,15 @@ def __init__(self, psi, source, A):
self._psi = psi

@classmethod
def construct(self, psi, operatorName, gamma=None, secondPsi=None):
def construct(self, psi, operatorName, gamma=None, cellPsi=None):

source, A = self.defineMatrix(psi, operatorName, gamma, secondPsi)
source, A = self.defineMatrix(psi, operatorName, gamma, cellPsi)

return self(psi, source, A)

@timed
def solve(self):
print('Solving system of equations\n')
print(f'Solving system of equations for field {self._psi._fieldName}\n')

# Create Krylov Subspace Solver
ksp = PETSc.KSP()
Expand All @@ -47,19 +48,19 @@ def solve(self):

# Solver settings
ksp.max_it = 1000
ksp.rtol = 1e-7
ksp.rtol = 1e-8
ksp.atol = 0

# Create right vector and solve system of equations
x = self._A.createVecRight()
ksp.solve(self._source, x)
print("\t Iterations= %d, residual norm = %g" % (ksp.its, ksp.norm))
print("\t Iterations= %d, residual norm = %g \n" % (ksp.its, ksp.norm))

# Get solution
sol = x.getArray()
# Solution is one big array, here it is divided into sublist to create
# vector or scalar value for each cell
dim = self._psi._dimensions
dim = self._psi.dim
self._psi._cellValues = [sol[i:i + dim].tolist() for i in range(0, len(sol), dim)]

# Evaluate boundary values
Expand All @@ -80,3 +81,33 @@ def __sub__(self, other):
A = self._A - other._A
source = self._source - other._source
return fvMatrix(self._psi, source, A)

def print(self, printPrecision=15):
self._A.convert('dense')
T = self._A.getDenseArray()
self._source.view()
np.set_printoptions(precision=printPrecision, suppress=True)
wr = [T[i:i + 1].tolist() for i in range(0, len(T), 1)]
for item in wr:
print(np.array(item))

def volOverD(self):
'''
Returns matrix inverse of diagonal coefficients multiplied with cell
volume. Used for SIMPLE algorithm.
'''
blockSize = self._psi.dim
vol = self._psi._mesh.V
diagTensors = []
for i in range(self._psi._mesh.nCells):
start = i * blockSize
end = (i + 1) * blockSize
# Get values of diagonal matrix for cell i
diag_block = self._A.getValues(range(start, end), range(start, end))

# Invert and multiply with cell volume
diag_block = np.linalg.inv(diag_block) * vol[i]

diagTensors.append(diag_block)

return diagTensors
3 changes: 2 additions & 1 deletion src/finiteVolume/fvMatrices/fvc/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .fvc import *
from .fvc import *
from .operators import *
4 changes: 2 additions & 2 deletions src/finiteVolume/fvMatrices/fvc/fvc.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
class fvc(fvMatrix):

@classmethod
def defineMatrix(self, psi, operatorName, gamma=None, secondPsi=None):
def defineMatrix(self, psi, operatorName, gamma=None, cellPsi=None):

# Make function for Laplacian, LaplacianTrace or LaplacianTranspose
operator = eval(operatorName + "." + "construct")

# Operator function returns A,b
return operator(psi, gamma, secondPsi)
return operator(psi, gamma, cellPsi)
5 changes: 4 additions & 1 deletion src/finiteVolume/fvMatrices/fvc/operators/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
from .grad import *
from .interpolate import *
from .interpolate import *
from .interpolateGrad import *
from .interpolateCellGrad import *
from .div import *
102 changes: 102 additions & 0 deletions src/finiteVolume/fvMatrices/fvc/operators/div.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
"""
_____ _____ _____ _____ _____ _____ | High-order Python FOAM
| | |___| _ |_ _| __| | _ | | | Python Version: 3.10
| | . | __| | | __| | | | | | | | Code Version: 0.0
|__|__|___|__| |_ |__| |_____|__|__|_|_|_| | License: GPLv3
|___|
Description
Explicit calculation of gradient at cell centres
"""
__author__ = 'Ivan Batistić & Philip Cardiff'
__email__ = 'ibatistic@fsb.hr, philip.cardiff@ucd.ie'
__all__ = ['div']


import os
from src.foam.foamFileParser import *
from petsc4py import PETSc
from src.finiteVolume.fvMatrices.fvc.operators.interpolate import interpolate

ADD = PETSc.InsertMode.ADD_VALUES

class div():

@classmethod
def construct(self, GaussPointsValues, gamma, cellPsi):

mesh = cellPsi._mesh
nCells = mesh.nCells

# Read PETSc options file
OptDB = PETSc.Options()

# Create empty left left-hand side matrix
A = PETSc.Mat()
A.create(comm=PETSc.COMM_WORLD)
A.setSizes((nCells, nCells))
A.setType(PETSc.Mat.Type.AIJ)
A.setUp()

# Create solution vector
source = A.createVecLeft()
source.set(0.0)
source.setUp()

# First loop over internal faces
for faceI in range(mesh.nInternalFaces):

# Face magnitude
magSf = mesh.magSf[faceI]

# Face normal
nf = mesh.nf[faceI]

faceGaussPointsAndWeights = cellPsi._facesGaussPointsAndWeights[faceI]

# Loop over Gauss points
for i, gp in enumerate(faceGaussPointsAndWeights[1]):

# Gauss point gp weight
gpW = faceGaussPointsAndWeights[0][i]

# Owner and neighbour of current face
cellP = mesh._owner[faceI]
cellN = mesh._neighbour[faceI]
value = gpW * magSf * (GaussPointsValues[faceI][i] @ nf)

source.setValues(cellP, value, ADD)
source.setValues(cellN, -value, ADD)

# Loop over boundary faces
for patch in cellPsi._boundaryConditionsDict:
startFace = mesh.boundary[patch]['startFace']
nFaces = mesh.boundary[patch]['nFaces']

# Loop over patch faces
for faceI in range(startFace, startFace + nFaces):

# Face magnitude
magSf = mesh.magSf[faceI]

# Face normal
nf = mesh.nf[faceI]

faceGaussPointsAndWeights = cellPsi._facesGaussPointsAndWeights[faceI]

# Loop over Gauss points
for i, gp in enumerate(faceGaussPointsAndWeights[1]):
# Gauss point gp weight
gpW = faceGaussPointsAndWeights[0][i]

# Owner and neighbour of current face
cellP = mesh._owner[faceI]
value = gpW * magSf * (GaussPointsValues[faceI][i] @ nf)

source.setValues(cellP, value, ADD)

# Finish matrix assembly
A.assemble()
source.assemble()

#source.view()
return source, A
Loading

0 comments on commit 17b9500

Please sign in to comment.