Giter VIP home page Giter VIP logo

knablat's Introduction

Knablat

Knablat (K \nabla T) is a conduction/diffusion solver based on FVM(Finite Volume Method) using unstructured grid. It is developed for the purpose of learning or teaching the FVM.

Features

Mesh/grid

It uses unstructured mesh of 3D. The mesh can be tetrahedron, hexahedron, prism, pyramid, or mixed.

The default mesh format is OpenFOAM mesh format. It can be converted from other mesh formats using tools by OpenFOAM, such as fluentMeshToFoam or ideasUnvToFoam.

And it is possible to write another mesh importer for other mesh formats. The default mesh importer is defined in ofmesh.py.

An ansys mesh(.msh) importer is provided in ansysmesh.py, which is modified from meshio.

Boundary condition

It supports the following boundary conditions.

  • Dirichlet
  • von Neumann
  • Robin or mixed

Cross diffusion correction

For non-orothogonal mesh, the cross diffusion correction is needed. Two gradient schemes are supported, the green-gauss-cell-based gradient scheme and the least square gradient scheme. And the least square gradient scheme is recommended.

Solver

It uses direct solver to solve the linear system of equations AX=b. The matrix A is stored in CSR sparse format(provided by scipy.sparse). The solver algrithm can be chosen from which is provided by scipy.sparse.linalg, such as CG, BiCGSTAB, GMRES, etc. If scikit-sparse is installed, the Cholesky decomposition can be used for better performance.

For unstructured mesh with cross diffusion correction, an iterative process is needed, and in each iteration, direct solver is used.

If the mesh is orthogonal, direct solver can be used without cross diffusion correction(Solver.solve_linear). And if the mesh is non-orothogonal, the cross diffusion correction is needed(use Solver.solve_unstructure).

Usage/examples

steps

  1. Prepare mesh file in OpenFOAM format.
  2. read mesh file and create mesh object.
  3. setup boundary conditions.
  4. setup network.
  5. solve equations.

setup boundary conditions

Boundary conditions are defined as a dictionary stored in mesh.boundary. The key is the name of boundary patch(defined in mesh file, for OpenFOAM mesh, it is defined in polyMesh/boundary), and the value is a Boundary object. The Boundary class has type, value, faces as attributes.

The types of boundary condition:

  • constant: Dirichlet boundary condition with constant value. The value is the constant value.
  • fixedFlux: von Neumann boundary condition with constant flux. The value is the constant flux.
  • convection: Robin boundary condition with constant convection coefficient and constant temperature. The value is a tuple of (convection coefficient, temperature).

Demo code for setting boundary condition:

    def set_boundary(self):
        """ set boundaries """
        self.mesh.boundary['bot_wall'].type = "constant"
        self.mesh.boundary['bot_wall'].value = 280.
        self.mesh.boundary['side_wall'].type = "convection"
        self.mesh.boundary['side_wall'].value = (1e4, 280.)
        self.mesh.boundary['hot_wall'].type = "fixedFlux"
        self.mesh.boundary['hot_wall'].value = 100000.

define the specific solver

For a specific problem, the specific solver should be defined. The solver is a class inherited from Solver class. The specific solver class should implement the following methods:

  • read_mesh: read mesh file and create mesh object.
  • set_boundary: setup boundary conditions.
  • others.

example

The example is in the directory examples/solver_test.py. It is used to solve heat conduction for different boundary conditions.

The main code is as follows:

import sys
import numpy as np
from knablat.solver import Solver
from knablat.ofmesh import read_of_mesh
from knablat.ansysmesh import read_ans_mesh

class TestSolver(Solver):
    """ class TestSolver """
    def __init__(self):
        super().__init__()
        
    def read_mesh(self, path: str):
        """ read mesh """
        if path.endswith('.msh'):
            self.mesh = read_ans_mesh(path)
        else:
            self.mesh = read_of_mesh(path)
        self.mesh.setup()
        
    def set_boundary(self):
        """ set boundaries """
        self.mesh.boundary['bot_wall'].type = "constant"
        self.mesh.boundary['bot_wall'].value = 280.
        self.mesh.boundary['hot_wall'].type = "fixedFlux"
        self.mesh.boundary['hot_wall'].value = 100000.
        
    def show_result(self, cross_diffusion: bool=False):
        """ show result """
        T_hot = (sum([fc.node.T*np.linalg.norm(fc.normal) for fc in self.mesh.boundary['hot_wall'].faces]) 
                 / sum([np.linalg.norm(fc.normal) for fc in self.mesh.boundary['hot_wall'].faces]))
        print(f'mean T_hot: {T_hot}')
        T_node_mean = sum([nd.T*nd.C for nd in self.inner_nodes]) / sum([nd.C for nd in self.inner_nodes])
        print(f'mean T_node: {T_node_mean}')
        Qin = self.acct_heat_flux('hot_wall', cross_diffusion)
        print(f'Qin: {Qin}')
        Qout = self.acct_heat_flux('bot_wall', cross_diffusion)
        print(f'Qout: {Qout}')
      
      
def test_solver(path: str, direct=False, method='spsolve', least_square=True):
    """ test solver """  
    solver = TestSolver()
    solver.read_mesh(path)
    solver.set_boundary()
    solver.setup_network(1., 1., 10., 300.)
    if direct:
        solver.solve_linear(method, use_umfpack=True)
    else:
        solver.solve_unstructure(criterion=1e-4, 
                                 use_cholesky=(method == 'cholesky'), 
                                 least_square=least_square,
                                 relax=0.99)
    solver.show_result(not direct)    
    
if __name__ == '__main__':
    if len(sys.argv) < 2:
        print('Usage: python solver_test.py <mesh_path>')
        sys.exit()
    test_solver(sys.argv[1], False, least_square=True)

There are two demo mesh in the directory examples/brick, they have the same geometry of a brick with size of 10 cm long, 5 cm width and 2 cm height. The directory tetra is a 3D tetrahedron mesh with 5831 cells. the directory hexa is a 3D hexahedron mesh with 800 cells.

To run the example:

python solver_test.py brick/tetra
python solver_test.py brick/hexa

In the example, the top surface of the brick is heating by a fixed flux of 100000 W/m^2, the bottom surface is set to a constant temperature of 280 K, and the other surfaces are adiabatic. The temperature of top surface can be easily calculated theoretically as 480 K(the conductance is 10 W/m-K). The results of the solver using tetrahedron mesh are as follows:

  • If solve the problem without cross diffusion correction, the temperature of top surface is 463.92 K, the error is 17 K.
  • If solve the problem with cross diffusion correction, and choose the green-gauss-cell-based gradient scheme, the temperature of top surface is 467.58 K, the error is 12.4 K.
  • If choose the least square gradient scheme, the temperature of top surface is almost 480K, the error is less than 1e-6 K.

If the top and bottom surface are set to constant temperature of 350 K and 280 K, respectively, and the other surfaces are adiabatic, the heat flux of top surface can be easily calculated theoretically as 175 W/m^2. The results of the solver using tetrahedron mesh are as follows:

  • If solve the problem without cross diffusion correction, the heat flux of top surface is 190.87 W/m^2, the error is 15.87 W/m^2.
  • If solve the problem with cross diffusion correction, and choose the green-gauss-cell-based gradient scheme, the heat flux of top surface is 186.66 W/m^2, the error is 11.66 W/m^2.
  • If choose the least square gradient scheme, the heat flux of top surface is 175.0 W/m^2, the error is less than 1e-5 W/m^2.

And for hexahedron mesh, the results are the same as theorectical results no matter whether cross diffusion correction is used or not.

Dependencies

  • numpy
  • scipy
  • scikit-sparse(optional), for Cholesky decomposition
  • Ofpp(optional), to import OpenFOAM mesh

knablat's People

Contributors

xu-xianghua avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.