fpakc/src/modules/output/moduleOutput.f90
JGonzalez ac27725940 Big one...
I should've commited before, but I wanted to make things compile.

The big change is that I've added a global time step so the parameter
does not need to be passed in each function. This is useful as we are
moving towards using time profiles for boundary conditions and injection
of particles (not in this branch, but in the future and the procedure
will be quite similar)
2024-07-12 23:08:19 +02:00

199 lines
6.3 KiB
Fortran

!Contains information about output
MODULE moduleOutput
IMPLICIT NONE
!Output for each node
TYPE, PUBLIC:: outputNode
REAL(8):: den = 0.D0, mom(1:3) = 0.D0, tensorS(1:3,1:3) = 0.D0
CONTAINS
PROCEDURE, PASS(self), PRIVATE:: outputNode_equal_outputNode
PROCEDURE, PASS(self), PRIVATE:: outputNode_equal_real
PROCEDURE, PASS(self), PRIVATE:: outputNode_add_outputNode
PROCEDURE, PASS(self), PRIVATE:: outputNode_sub_outputNode
PROCEDURE, PASS(self), PRIVATE:: outputNode_mul_outputNode
PROCEDURE, PASS(self), PRIVATE:: outputNode_div_int
GENERIC, PUBLIC :: ASSIGNMENT(=) => outputNode_equal_outputNode, outputNode_equal_real
GENERIC, PUBLIC :: OPERATOR(+) => outputNode_add_outputNode
GENERIC, PUBLIC :: OPERATOR(-) => outputNode_sub_outputNode
GENERIC, PUBLIC :: OPERATOR(*) => outputNode_mul_outputNode
GENERIC, PUBLIC :: OPERATOR(/) => outputNode_div_int
END TYPE
!Type for EM data in node
TYPE emNode
CHARACTER(:), ALLOCATABLE:: type
REAL(8):: phi
REAL(8):: B(1:3)
END TYPE emNode
!Output in dimensional units to print
TYPE outputFormat
REAL(8):: density, velocity(1:3), pressure, temperature
END TYPE
CHARACTER(:), ALLOCATABLE:: path
CHARACTER(:), ALLOCATABLE:: folder
INTEGER:: iterationDigits
CHARACTER(:), ALLOCATABLE:: iterationFormat
INTEGER:: triggerOutput, counterOutput = 0
INTEGER:: triggerCPUTime, counterCPUTime = 0
LOGICAL:: timeOutput = .FALSE.
LOGICAL:: collOutput = .FALSE.
LOGICAL:: emOutput = .FALSE.
CONTAINS
PURE SUBROUTINE outputNode_equal_outputNode(self, from)
IMPLICIT NONE
CLASS(outputNode), INTENT(inout):: self
CLASS(outputNode), INTENT(in):: from
self%den = from%den
self%mom = from%mom
self%tensorS = from%tensorS
END SUBROUTINE outputNode_equal_outputNode
PURE ELEMENTAL SUBROUTINE outputNode_equal_real(self, from)
IMPLICIT NONE
CLASS(outputNode), INTENT(inout):: self
REAL(8), INTENT(in):: from
self%den = from
self%mom = from
self%tensorS = from
END SUBROUTINE outputNode_equal_real
PURE ELEMENTAL FUNCTION outputNode_add_outputNode(self, that) RESULT(total)
IMPLICIT NONE
CLASS(outputNode), INTENT(in):: self
CLASS(outputNode), INTENT(in):: that
TYPE(outputNode):: total
total%den = self%den + that%den
total%mom = self%mom + that%mom
total%tensorS = self%tensorS + that%tensorS
END FUNCTION outputNode_add_outputNode
PURE ELEMENTAL FUNCTION outputNode_sub_outputNode(self, that) RESULT(total)
IMPLICIT NONE
CLASS(outputNode), INTENT(in):: self
CLASS(outputNode), INTENT(in):: that
TYPE(outputNode):: total
total%den = self%den - that%den
total%mom = self%mom - that%mom
total%tensorS = self%tensorS - that%tensorS
END FUNCTION outputNode_sub_outputNode
PURE ELEMENTAL FUNCTION outputNode_mul_outputNode(self, that) RESULT(total)
IMPLICIT NONE
CLASS(outputNode), INTENT(in):: self
CLASS(outputNode), INTENT(in):: that
TYPE(outputNode):: total
total%den = self%den * that%den
total%mom = self%mom * that%mom
total%tensorS = self%tensorS * that%tensorS
END FUNCTION outputNode_mul_outputNode
PURE ELEMENTAL FUNCTION outputNode_div_int(self, that) RESULT(total)
IMPLICIT NONE
CLASS(outputNode), INTENT(in):: self
INTEGER, INTENT(in):: that
TYPE(outputNode):: total
total%den = self%den / REAL(that)
total%mom = self%mom / REAL(that)
total%tensorS = self%tensorS / REAL(that)
END FUNCTION outputNode_div_int
SUBROUTINE calculateOutput(rawValues, formatValues, nodeVol, speciesIn)
USE moduleConstParam
USE moduleRefParam
USE moduleSpecies
USE moduleMath
IMPLICIT NONE
TYPE(outputNode), INTENT(in):: rawValues
TYPE(outputFormat), INTENT(out):: formatValues
REAL(8), INTENT(in):: nodeVol
CLASS(speciesGeneric), INTENT(in):: speciesIn
REAL(8), DIMENSION(1:3,1:3):: tensorTemp
REAL(8), DIMENSION(1:3):: tempVel
REAL(8):: tempVol
!Resets the node outputs
formatValues%density = 0.D0
formatValues%velocity = 0.D0
formatValues%pressure = 0.D0
formatValues%temperature = 0.D0
tempVol = 1.D0/(nodeVol*Vol_ref)
IF (rawValues%den > 0.D0) THEN
tempVel = rawValues%mom(:)/rawValues%den
tensorTemp = (rawValues%tensorS(:,:) - rawValues%den*outerProduct(tempVel,tempVel))
formatValues%density = rawValues%den*tempVol
formatValues%velocity(:) = tempVel
IF (tensorTrace(tensorTemp) > 0.D0) THEN
formatValues%pressure = speciesIn%m*tensorTrace(tensorTemp)*tempVol/3.D0
formatValues%temperature = formatValues%pressure/(formatValues%density*kb)
END IF
END IF
formatValues%velocity = formatValues%velocity*v_ref
formatValues%pressure = formatValues%pressure*m_ref*v_ref**2
formatValues%temperature = formatValues%temperature*m_ref*v_ref**2
END SUBROUTINE calculateOutput
SUBROUTINE printTime(first)
USE moduleSpecies
USE moduleCompTime
USE moduleCaseParam, ONLY: timeStep
IMPLICIT NONE
LOGICAL, INTENT(in), OPTIONAL:: first
CHARACTER(:), ALLOCATABLE:: fileName
fileName = 'cpuTime.dat'
IF (timeOutput) THEN
IF (PRESENT(first)) THEN
IF (first) THEN
OPEN(20, file = path // folder // '/' // fileName, action = 'write')
WRITE(20, "(A1, 8X, A1, 9X, A1, 7(A20))") "#","t","n","total (s)","push (s)","reset (s)", &
"collision (s)","coulomb (s)", &
"weighting (s)","EMField (s)"
WRITE(*, "(6X,A15,A)") "Creating file: ", fileName
CLOSE(20)
END IF
END IF
OPEN(20, file = path // folder // '/' // fileName, position = 'append', action = 'write')
WRITE (20, "(I10, I10, 7(ES20.6E3))") timeStep, nPartOld, tStep, tPush, tReset, tColl, tCoul, tWeight, tEMField
CLOSE(20)
END IF
END SUBROUTINE printTime
END MODULE moduleOutput