First commit of code.
New functionality:
- DSMC module:
- 2D cyl geometry
- GMSH file format
- Elastic cross-section for Argon-Argon collisions.
- Basic boundary conditions: reflection, absorption and axis
symmetry.
Bugs fixed:
Other comments:
- Still searching for name.
This commit is contained in:
commit
bd7e8b040b
29 changed files with 4069 additions and 0 deletions
366
src/modules/moduleInput.f95
Normal file
366
src/modules/moduleInput.f95
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
! moduleInput: Reads JSON configuration file
|
||||
MODULE moduleInput
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
||||
CONTAINS
|
||||
!Main routine to read the input JSON file
|
||||
SUBROUTINE readConfig(inputFile)
|
||||
USE json_module
|
||||
USE moduleErrors
|
||||
USE moduleBoundary
|
||||
USE moduleInject
|
||||
IMPLICIT NONE
|
||||
|
||||
CHARACTER(:), ALLOCATABLE, INTENT(in):: inputFile
|
||||
TYPE(json_file):: config
|
||||
|
||||
!Initialize the json file variable
|
||||
CALL config%initialize()
|
||||
|
||||
!Loads the config file
|
||||
CALL config%load(filename = inputFile)
|
||||
|
||||
!Reads reference parameters
|
||||
CALL readReference(config)
|
||||
|
||||
!Reads case parameters
|
||||
CALL readCase(config)
|
||||
|
||||
!Reads output parameters
|
||||
CALL readOutput(config)
|
||||
|
||||
!Read species
|
||||
CALL readSpecies(config)
|
||||
|
||||
!Read interactions between species
|
||||
CALL readInteractions(config)
|
||||
|
||||
!Read boundaries
|
||||
CALL readBoundary(config)
|
||||
|
||||
!Read Geometry
|
||||
CALL readGeometry(config)
|
||||
|
||||
!Read injection of particles
|
||||
CALL readInject(config)
|
||||
|
||||
END SUBROUTINE readConfig
|
||||
|
||||
!Reads the reference parameters
|
||||
SUBROUTINE readReference(config)
|
||||
USE moduleRefParam
|
||||
USE moduleConstParam
|
||||
USE moduleErrors
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
LOGICAL:: found
|
||||
CHARACTER(:), ALLOCATABLE:: object
|
||||
|
||||
object = 'reference'
|
||||
!Mandatory parameters that define the case and computes derived parameters
|
||||
CALL config%get(object // '.density', n_ref, found)
|
||||
IF (.NOT. found) CALL criticalError('Reference density not found','readReference')
|
||||
|
||||
CALL config%get(object // '.mass', m_ref, found)
|
||||
IF (.NOT. found) CALL criticalError('Reference mass not found','readReference')
|
||||
|
||||
CALL config%get(object // '.temperature', T_ref, found)
|
||||
IF (.NOT. found) CALL criticalError('Reference temperature not found','readReference')
|
||||
|
||||
CALL config%get(object // '.radius', r_ref, found)
|
||||
IF (.NOT. found) CALL criticalError('Reference radius not found','readReference')
|
||||
|
||||
!Derived parameters
|
||||
sigma_ref = PI*(r_ref+r_ref)**2 !reference cross section
|
||||
L_ref = 1.D0/(sigma_ref*n_ref) !mean free path
|
||||
ti_ref = L_ref/v_ref !reference time
|
||||
Vol_ref = L_ref**3 !reference volume
|
||||
v_ref = DSQRT(kb*T_ref/m_ref) !reference velocity
|
||||
|
||||
END SUBROUTINE readReference
|
||||
|
||||
!Reads the specific case parameters
|
||||
SUBROUTINE readCase(config)
|
||||
USE moduleRefParam
|
||||
USE moduleErrors
|
||||
USE moduleCaseParam
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
LOGICAL:: found
|
||||
CHARACTER(:), ALLOCATABLE:: object
|
||||
REAL(8):: time !simulation time in [t]
|
||||
|
||||
object = 'case'
|
||||
!Time parameters
|
||||
CALL config%get(object // '.tau', tau, found)
|
||||
IF (.NOT. found) CALL criticalError('Required parameter tau not found','readCase')
|
||||
|
||||
CALL config%get(object // '.time', time, found)
|
||||
IF (.NOT. found) CALL criticalError('Required parameter time not found','readCase')
|
||||
|
||||
!Convert simulation time to number of iterations
|
||||
tmax = INT(time/(ti_ref*tau))
|
||||
|
||||
END SUBROUTINE readCase
|
||||
|
||||
!Reads configuration for the output files
|
||||
SUBROUTINE readOutput(config)
|
||||
USE moduleErrors
|
||||
USE moduleOutput
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
LOGICAL:: found
|
||||
CHARACTER(:), ALLOCATABLE:: object
|
||||
CHARACTER(8) :: date_now=''
|
||||
CHARACTER(10) :: time_now=''
|
||||
|
||||
object = 'output'
|
||||
CALL config%get(object // '.path', path, found)
|
||||
CALL config%get(object // '.trigger', triggerOutput, found)
|
||||
IF (.NOT. found) THEN
|
||||
triggerOutput = 100
|
||||
CALL warningError('Using default trigger for output file of 100 iterations')
|
||||
|
||||
END IF
|
||||
|
||||
!Creates output folder
|
||||
!TODO: Add option for custon name output_folder
|
||||
CALL DATE_AND_TIME(date_now, time_now)
|
||||
folder = date_now(1:4) // '-' // date_now(5:6) // '-' // date_now(7:8) // '_' &
|
||||
// time_now(1:2) // '.' // time_now(3:4) // '.' // time_now(5:6)
|
||||
CALL SYSTEM('mkdir ' // path // folder )
|
||||
|
||||
CALL config%get(object // '.cpuTime', timeOutput, found)
|
||||
CALL config%get(object // '.numColl', collOutput, found)
|
||||
|
||||
END SUBROUTINE readOutput
|
||||
|
||||
!Reads information about the case species
|
||||
SUBROUTINE readSpecies(config)
|
||||
USE moduleSpecies
|
||||
USE moduleErrors
|
||||
USE moduleRefParam
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
CHARACTER(2):: iString
|
||||
CHARACTER(:), ALLOCATABLE:: object
|
||||
CHARACTER(:), ALLOCATABLE:: speciesType
|
||||
REAL(8):: mass
|
||||
LOGICAL:: found
|
||||
INTEGER:: i
|
||||
|
||||
!Gets the number of species
|
||||
CALL config%info('species', n_children = nSpecies)
|
||||
!Zero species means critical error
|
||||
IF (nSpecies == 0) CALL criticalError("No species found", "configRead")
|
||||
|
||||
ALLOCATE(species(1:nSpecies))
|
||||
|
||||
!Reads information of individual species
|
||||
DO i = 1, nSpecies
|
||||
WRITE(iString, '(I2)') i
|
||||
object = 'species(' // TRIM(iString) // ')'
|
||||
CALL config%get(object // '.type', speciesType, found)
|
||||
|
||||
SELECT CASE(speciesType)
|
||||
CASE ("neutral")
|
||||
ALLOCATE(species(i)%obj, source=speciesNeutral())
|
||||
!TODO: move to subroutine
|
||||
CALL config%get(object // '.name', species(i)%obj%name, found)
|
||||
CALL config%get(object // '.mass', mass, found)
|
||||
CALL config%get(object // '.weight', species(i)%obj%weight, found)
|
||||
species(i)%obj%pt = i
|
||||
species(i)%obj%m = mass/m_ref
|
||||
|
||||
CASE DEFAULT
|
||||
CALL warningError("Species " // speciesType // " not supported yet")
|
||||
|
||||
END SELECT
|
||||
|
||||
END DO
|
||||
|
||||
!Set number of particles to 0 for init state
|
||||
!TODO: In a future, this should include the particles from init states
|
||||
n_part_old = 0
|
||||
|
||||
END SUBROUTINE readSpecies
|
||||
|
||||
!Reads information about interactions between species
|
||||
SUBROUTINE readInteractions(config)
|
||||
USE moduleSpecies
|
||||
USE moduleCollisions
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
CHARACTER(2):: iString, kString
|
||||
CHARACTER(:), ALLOCATABLE:: object
|
||||
CHARACTER(:), ALLOCATABLE:: species_i, species_j
|
||||
CHARACTER(:), ALLOCATABLE:: crossSecFile
|
||||
CHARACTER(:), ALLOCATABLE:: crossSecFilePath
|
||||
INTEGER:: nInteractions, nCollisions
|
||||
INTEGER:: i, k, ij
|
||||
INTEGER:: pt_i, pt_j
|
||||
|
||||
CALL initInteractionMatrix(interactionMatrix)
|
||||
|
||||
CALL config%get('interactions.folderCollisions', pathCollisions)
|
||||
|
||||
CALL config%info('interactions.collisions', n_children = nInteractions)
|
||||
DO i = 1, nInteractions
|
||||
WRITE(iString, '(I2)') i
|
||||
object = 'interactions.collisions(' // TRIM(iString) // ')'
|
||||
CALL config%get(object // '.species_i', species_i)
|
||||
pt_i = speciesName2Index(species_i)
|
||||
CALL config%get(object // '.species_j', species_j)
|
||||
pt_j = speciesName2Index(species_j)
|
||||
CALL config%info(object // '.crossSections', n_children = nCollisions)
|
||||
ij = interactionIndex(pt_i,pt_j)
|
||||
CALL interactionMatrix(ij)%init(nCollisions)
|
||||
|
||||
DO k = 1, nCollisions
|
||||
WRITE (kString, '(I2)') k
|
||||
CALL config%get(object // '.crossSections(' // TRIM(kString)// ')', crossSecFile)
|
||||
crossSecFilePath = pathCollisions // crossSecFile
|
||||
CALL interactionMatrix(ij)%collisions(k)%obj%init(crossSecFilePath)
|
||||
|
||||
END DO
|
||||
|
||||
END DO
|
||||
|
||||
|
||||
END SUBROUTINE readInteractions
|
||||
|
||||
!Reads boundary conditions for the mesh
|
||||
SUBROUTINE readBoundary(config)
|
||||
USE moduleBoundary
|
||||
USE moduleErrors
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
CHARACTER(2):: istring
|
||||
CHARACTER(:), ALLOCATABLE:: object
|
||||
LOGICAL:: found
|
||||
INTEGER:: i
|
||||
|
||||
CALL config%info('boundary', n_children = nBoundary)
|
||||
ALLOCATE(boundary(1:nBoundary))
|
||||
DO i = 1, nBoundary
|
||||
WRITE(istring, '(i2)') i
|
||||
object = 'boundary(' // trim(istring) // ')'
|
||||
|
||||
ALLOCATE(boundaryGeneric:: boundary(i)%obj)
|
||||
|
||||
CALL config%get(object // '.type', boundary(i)%obj%boundaryType, found)
|
||||
CALL config%get(object // '.physicalSurface', boundary(i)%obj%physicalSurface, found)
|
||||
boundary(i)%obj%id = i
|
||||
|
||||
END DO
|
||||
|
||||
END SUBROUTINE readBoundary
|
||||
|
||||
!Read the geometry (mesh) for the case
|
||||
SUBROUTINE readGeometry(config)
|
||||
USE moduleMesh
|
||||
USE moduleMeshCylRead
|
||||
USE moduleErrors
|
||||
USE moduleOutput
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
LOGICAL:: found
|
||||
CHARACTER(:), ALLOCATABLE:: geometryType, meshType, meshFile
|
||||
CHARACTER(:), ALLOCATABLE:: fullPath
|
||||
|
||||
!Selects the type of geometry.
|
||||
CALL config%get('geometry.type', geometryType, found)
|
||||
SELECT CASE(geometryType)
|
||||
CASE ("2DCyl")
|
||||
!Creates a 2D cylindrical mesh
|
||||
ALLOCATE(meshCylGeneric:: mesh)
|
||||
|
||||
!Gets the type of mesh
|
||||
CALL config%get('geometry.meshType', meshType, found)
|
||||
SELECT CASE(meshType)
|
||||
CASE ("gmsh")
|
||||
!Gets the gmsh file
|
||||
CALL config%get('geometry.meshFile', meshFile, found)
|
||||
|
||||
CASE DEFAULT
|
||||
CALL criticalError("Mesh type " // meshType // " not supported.", "readGeometry")
|
||||
|
||||
END SELECT
|
||||
!Reads the mesh
|
||||
fullpath = path // meshFile
|
||||
CALL mesh%readMesh(fullPath)
|
||||
|
||||
CASE DEFAULT
|
||||
CALL criticalError("Geometry type " // geometryType // " not supported.", "readGeometry")
|
||||
|
||||
END SELECT
|
||||
|
||||
END SUBROUTINE readGeometry
|
||||
|
||||
!Reads the injection of particles from the boundaries
|
||||
SUBROUTINE readInject(config)
|
||||
USE moduleSpecies
|
||||
USE moduleErrors
|
||||
USE moduleInject
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
INTEGER:: i
|
||||
character(2):: istring
|
||||
character(:), allocatable:: object
|
||||
logical:: found
|
||||
CHARACTER(:), ALLOCATABLE:: speciesName
|
||||
CHARACTER(:), ALLOCATABLE:: name
|
||||
REAL(8):: v
|
||||
REAL(8), ALLOCATABLE:: T(:), normal(:)
|
||||
REAL(8):: flow
|
||||
INTEGER:: physicalSurface
|
||||
INTEGER:: pt
|
||||
|
||||
CALL config%info('inject', n_children = nInject)
|
||||
ALLOCATE(inject(1:nInject))
|
||||
nPartInj = 0
|
||||
DO i = 1, nInject
|
||||
WRITE(istring, '(i2)') i
|
||||
object = 'inject(' // trim(istring) // ')'
|
||||
|
||||
!Find species
|
||||
CALL config%get(object // '.species', speciesName, found)
|
||||
pt = speciesName2Index(speciesName)
|
||||
|
||||
CALL config%get(object // '.name', name, found)
|
||||
CALL config%get(object // '.v', v, found)
|
||||
CALL config%get(object // '.T', T, found)
|
||||
CALL config%get(object // '.n', normal, found)
|
||||
CALL config%get(object // '.flow', flow, found)
|
||||
CALL config%get(object // '.physicalSurface', physicalSurface, found)
|
||||
|
||||
CALL inject(i)%init(i, v, normal, T, flow, pt, physicalSurface)
|
||||
|
||||
END DO
|
||||
|
||||
!Allocate array for injected particles
|
||||
IF (nPartInj > 0) THEN
|
||||
ALLOCATE(part_inj(1:nPartInj))
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE readInject
|
||||
|
||||
END MODULE moduleInput
|
||||
Loading…
Add table
Add a link
Reference in a new issue