Linear Euler 2D with a Perfectly Matched Layer (PML) absorbing region.
Formulation: Hu (2001), "A Stable, Perfectly Matched Layer for Linearized Euler Equations in Unsplit Physical Variables" (JCP 173, 455-480), in the ADE (Auxiliary Differential Equation) form for the no-mean-flow case.
In the PML region the dynamics for the acoustic state q = (rho', u, v, p) become
dq/dt + A dq/dx + B dq/dy + (sigma_x + sigma_y) q + sigma_x*sigma_y phi = 0 dphi/dt = q
where phi = (phi_rho, phi_u, phi_v, phi_P) is a 4-component auxiliary that accumulates the time integral of q. The sigma_x(x), sigma_y(y) damping coefficients vanish in the interior and rise toward the outer boundary, leaving the original linear Euler 2D dynamics unaltered where sigma = 0.
Solution layout (nvar = 9): s(1) = rho (density perturbation) s(2) = u (x-velocity) s(3) = v (y-velocity) s(4) = P (pressure perturbation) s(5) = c (sound speed, static; per-node) s(6) = phi_rho (auxiliary; time-integral of rho) s(7) = phi_u (auxiliary; time-integral of u) s(8) = phi_v (auxiliary; time-integral of v) s(9) = phi_P (auxiliary; time-integral of P)
The auxiliary variables phi_* have identically zero flux; they evolve only via the source term. Sound speed c is also static (zero flux, zero source) and is preserved from the parent LinearEuler2D model.
PML elements are identified by a material name beginning with the configurable prefix (default "pml") in the mesh's material table. Non-PML elements always carry sigma_x = sigma_y = 0 and therefore reduce to the parent linear Euler 2D dynamics (modulo the inert auxiliary variables, which remain identically zero there).
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| type(MappedScalar2D), | public | :: | dSdt | ||||
| real(kind=prec), | public | :: | dt | ||||
| real(kind=prec), | public | :: | entropy | ||||
| type(MappedVector2D), | public | :: | flux | ||||
| type(MappedScalar2D), | public | :: | fluxDivergence | ||||
| real(kind=prec), | public | :: | g | = | 0.0_prec | ||
| type(SEMQuad), | public, | pointer | :: | geometry | |||
| logical, | public | :: | gradient_enabled | = | .false. | ||
| type(BoundaryConditionList), | public | :: | hyperbolicBCs | ||||
| integer, | public | :: | ioIterate | = | 0 | ||
| type(Mesh2D), | public, | pointer | :: | mesh | |||
| integer, | public | :: | nvar | ||||
| type(BoundaryConditionList), | public | :: | parabolicBCs | ||||
| character(len=SELF_MESH_MATNAME_LENGTH), | public | :: | pml_material_prefix | = | "pml" | ||
| integer, | public | :: | pml_ramp_exponent | = | 3 | ||
| real(kind=prec), | public | :: | pml_sigma_max | = | 0.0_prec | ||
| real(kind=prec), | public | :: | pml_width | = | 1.0_prec | ||
| real(kind=prec), | public | :: | pml_x_max | = | 0.0_prec | ||
| real(kind=prec), | public | :: | pml_x_min | = | 0.0_prec | ||
| real(kind=prec), | public | :: | pml_y_max | = | 0.0_prec | ||
| real(kind=prec), | public | :: | pml_y_min | = | 0.0_prec | ||
| logical, | public | :: | prescribed_bcs_enabled | = | .true. | ||
| real(kind=prec), | public | :: | rho0 | = | 1.0_prec | ||
| type(MappedScalar2D), | public | :: | sigma_x | ||||
| type(MappedScalar2D), | public | :: | sigma_y | ||||
| type(MappedScalar2D), | public | :: | solution | ||||
| type(MappedVector2D), | public | :: | solutionGradient | ||||
| type(MappedScalar2D), | public | :: | source | ||||
| real(kind=prec), | public | :: | t | ||||
| logical, | public | :: | tecplot_enabled | = | .true. | ||
| procedure(SELF_timeIntegrator), | public, | pointer | :: | timeIntegrator | => | Euler_timeIntegrator | |
| type(MappedScalar2D), | public | :: | workSol |
| procedure, public :: AdditionalFree => AdditionalFree_LinearEuler2D_PML_t | |
| procedure, public :: AdditionalInit => AdditionalInit_LinearEuler2D_PML_t | |
| procedure, public :: AdditionalOutput => AdditionalOutput_Model | |
| procedure, public :: BoundaryFlux => BoundaryFlux_DGModel2D | |
| procedure, public :: CalculateEntropy => CalculateEntropy_DGModel2D | |
| procedure, public :: CalculateSolutionGradient => CalculateSolutionGradient_DGModel2D | |
| procedure, public :: CalculateTendency => CalculateTendency_DGModel2D | |
| procedure, public :: Euler_timeIntegrator | |
| procedure, public :: FluxMethod => fluxmethod_DGModel2D | |
| procedure, public :: ForwardStep => ForwardStep_Model | |
| procedure, public :: Free => Free_DGModel2D | |
| procedure, public :: GetSimulationTime | |
| procedure, public :: IncrementIOCounter | |
| procedure, public :: Init => Init_DGModel2D | |
| procedure, public :: LowStorageRK2_timeIntegrator | |
| procedure, public :: LowStorageRK3_timeIntegrator | |
| procedure, public :: LowStorageRK4_timeIntegrator | |
| procedure, public :: MapBoundaryConditions => MapBoundaryConditions_DGModel2D_t | |
| procedure, public :: PreTendency => PreTendency_Model | |
| procedure, public :: PrintType => PrintType_Model | |
| procedure, public :: ReadModel => Read_DGModel2D_t | |
| procedure, public :: ReportEntropy => ReportEntropy_Model | |
| procedure, public :: ReportMetrics => ReportMetrics_DGModel2D_t | |
| procedure, public :: ReportUserMetrics => ReportUserMetrics_Model | |
| procedure, public :: SetBoundaryCondition => setboundarycondition_DGModel2D_t | |
| procedure, public :: SetGradientBoundaryCondition => setgradientboundarycondition_DGModel2D_t | |
| procedure, public :: SetMetadata => SetMetadata_LinearEuler2D_PML_t | |
| procedure, public :: SetNumberOfVariables => SetNumberOfVariables_LinearEuler2D_PML_t | |
| procedure, public :: SetPMLProfile => SetPMLProfile_LinearEuler2D_PML_t | |
| procedure, public :: SetSimulationTime | |
| generic, public :: SetSolution => SetSolutionFromChar_DGModel2D_t, SetSolutionFromEqn_DGModel2D_t | |
| generic, public :: SetTimeIntegrator => SetTimeIntegrator_withChar | |
| procedure, public :: SphericalSoundWave => SphericalSoundWave_LinearEuler2D_t | |
| procedure, public :: UpdateGRK2 => UpdateGRK2_DGModel2D | |
| procedure, public :: UpdateGRK3 => UpdateGRK3_DGModel2D | |
| procedure, public :: UpdateGRK4 => UpdateGRK4_DGModel2D | |
| procedure, public :: UpdateSolution => UpdateSolution_DGModel2D | |
| procedure, public :: WriteModel => Write_DGModel2D_t | |
| procedure, public :: WriteTecplot => WriteTecplot_DGModel2D_t | |
| procedure, public :: entropy_func => entropy_func_LinearEuler2D_t | |
| procedure, public :: flux1D => flux1d_Model | |
| procedure, public :: flux2d => flux2d_LinearEuler2D_PML_t | |
| procedure, public :: flux3D => flux3d_Model | |
| procedure, public :: riemannflux1d => riemannflux1d_Model | |
| procedure, public :: riemannflux2d => riemannflux2d_LinearEuler2D_PML_t | |
| procedure, public :: riemannflux3d => riemannflux3d_Model | |
| procedure, public :: source1d => source1d_Model | |
| procedure, public :: source2d => source2d_Model | |
| procedure, public :: source3d => source3d_Model | |
| procedure, public :: sourcemethod => sourcemethod_LinearEuler2D_PML_t |
Interior flux. Variables 1-5 use the parent linear Euler 2D flux; auxiliary variables 6-9 carry zero flux in both directions and are evolved purely by the PML source term.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LinearEuler2D_PML_t), | intent(in) | :: | this | |||
| real(kind=prec), | intent(in) | :: | s(1:this%nvar) | |||
| real(kind=prec), | intent(in) | :: | dsdx(1:this%nvar,1:2) |
Impedance-matched Riemann flux for acoustic variables 1-5, with zero flux returned for the auxiliary variables 6-9. The acoustic formula is identical to the parent LinearEuler2D model; see riemannflux2d_LinearEuler2D_t for the derivation.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LinearEuler2D_PML_t), | intent(in) | :: | this | |||
| real(kind=prec), | intent(in) | :: | sL(1:this%nvar) | |||
| real(kind=prec), | intent(in) | :: | sR(1:this%nvar) | |||
| real(kind=prec), | intent(in) | :: | dsdx(1:this%nvar,1:2) | |||
| real(kind=prec), | intent(in) | :: | nhat(1:2) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LinearEuler2D_PML_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LinearEuler2D_PML_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LinearEuler2D_PML_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LinearEuler2D_PML_t), | intent(inout) | :: | this |
Populate the per-node sigma_x, sigma_y fields. Only nodes inside elements whose material name starts with this%pml_material_prefix receive non-zero damping; all other nodes are forced to zero so the interior solution remains unmodified.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LinearEuler2D_PML_t), | intent(inout) | :: | this | |||
| real(kind=prec), | intent(in) | :: | x_interior_min | |||
| real(kind=prec), | intent(in) | :: | x_interior_max | |||
| real(kind=prec), | intent(in) | :: | y_interior_min | |||
| real(kind=prec), | intent(in) | :: | y_interior_max | |||
| real(kind=prec), | intent(in) | :: | pml_width | |||
| real(kind=prec), | intent(in) | :: | sigma_max | |||
| integer, | intent(in), | optional | :: | ramp_exponent |
No-normal-flow BC for the PML-augmented linear Euler model. Variables 1-5 are treated identically to the parent LinearEuler2D no-normal-flow BC. Auxiliary variables 6-9 are given a zero exterior state; since they carry zero Riemann flux the exterior value is mathematically irrelevant, but zeroing it keeps the boundary state clean for diagnostics.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(BoundaryCondition), | intent(in) | :: | bc | |||
| class(Model), | intent(inout) | :: | mymodel |
Radiation BC for the PML-augmented linear Euler model: zero acoustic perturbation in the exterior state, sound speed copied from interior so the Riemann solver sees a consistent c, and auxiliary variables set to zero.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(BoundaryCondition), | intent(in) | :: | bc | |||
| class(Model), | intent(inout) | :: | mymodel |
Hu (2001) unsplit PML source term, evaluated per node. In the interior (sigma_x = sigma_y = 0) this leaves the acoustic variables untouched and the auxiliaries integrate q in time but never re-enter the dynamics (since the coupling coefficient sigma_xsigma_y is zero). Inside the PML, the (sigma_x + sigma_y) damping plus the sigma_xsigma_y*phi term produce the correct perfectly-matched behaviour for the linear Euler 2D system.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LinearEuler2D_PML_t), | intent(inout) | :: | this |