Path: blob/devel/fem/tests/1dtests_MeshLevels/Poisson.f90
5255 views
SUBROUTINE PoissonSolver( Model,Solver,dt,TransientSimulation )1!------------------------------------------------------------------------------2!******************************************************************************3!4! Solve the Poisson equation!5!6! ARGUMENTS:7!8! TYPE(Model_t) :: Model,9! INPUT: All model information (mesh, materials, BCs, etc...)10!11! TYPE(Solver_t) :: Solver12! INPUT: Linear & nonlinear equation solver options13!14! REAL(KIND=dp) :: dt,15! INPUT: Timestep size for time dependent simulations16!17! LOGICAL :: TransientSimulation18! INPUT: Steady state or transient simulation19!20!******************************************************************************21USE DefUtils2223IMPLICIT NONE24!------------------------------------------------------------------------------25TYPE(Solver_t) :: Solver26TYPE(Model_t) :: Model2728REAL(KIND=dp) :: dt29LOGICAL :: TransientSimulation30!------------------------------------------------------------------------------31! Local variables32!------------------------------------------------------------------------------33TYPE(Element_t),POINTER :: Element3435LOGICAL :: AllocationsDone = .FALSE., Found3637INTEGER :: n, t, istat, active38REAL(KIND=dp) :: Norm3940TYPE(ValueList_t), POINTER :: BodyForce41TYPE(Mesh_t), POINTER :: Mesh42REAL(KIND=dp), ALLOCATABLE :: STIFF(:,:), LOAD(:), FORCE(:)4344SAVE STIFF, LOAD, FORCE, AllocationsDone45!------------------------------------------------------------------------------4647Mesh => GetMesh()4849!Allocate some permanent storage, this is done first time only:50!--------------------------------------------------------------51IF ( .NOT. AllocationsDone ) THEN52N = Mesh % MaxElementNodes ! just big enough for elemental arrays53ALLOCATE( FORCE(N), LOAD(N), STIFF(N,N), STAT=istat )54IF ( istat /= 0 ) THEN55CALL Fatal( 'PoissonSolve', 'Memory allocation error.' )56END IF57AllocationsDone = .TRUE.58END IF5960!Initialize the system and do the assembly:61!------------------------------------------62CALL DefaultInitialize()6364active = GetNOFActive()65DO t=1,active66Element => GetActiveElement(t)67n = GetElementNOFNodes()6869LOAD = 0.0d070BodyForce => GetBodyForce()71IF ( ASSOCIATED(BodyForce) ) &72Load(1:n) = GetReal( BodyForce, 'Source', Found )7374!Get element local matrix and rhs vector:75!----------------------------------------76CALL LocalMatrix( STIFF, FORCE, LOAD, Element, n )7778!Update global matrix and rhs vector from local matrix & vector:79!---------------------------------------------------------------80CALL DefaultUpdateEquations( STIFF, FORCE )81END DO8283CALL DefaultFinishAssembly()84CALL DefaultDirichletBCs()85Norm = DefaultSolve()8687CONTAINS8889!------------------------------------------------------------------------------90SUBROUTINE LocalMatrix( STIFF, FORCE, LOAD, Element, n )91!------------------------------------------------------------------------------92REAL(KIND=dp) :: STIFF(:,:), FORCE(:), LOAD(:)93INTEGER :: n94TYPE(Element_t), POINTER :: Element95!------------------------------------------------------------------------------96REAL(KIND=dp) :: Basis(n),dBasisdx(n,3),DetJ,LoadAtIP97LOGICAL :: Stat98INTEGER :: t99TYPE(GaussIntegrationPoints_t) :: IP100101TYPE(Nodes_t) :: Nodes102SAVE Nodes103!------------------------------------------------------------------------------104CALL GetElementNodes( Nodes )105STIFF = 0.0d0106FORCE = 0.0d0107108!Numerical integration:109!----------------------110IP = GaussPoints( Element )111DO t=1,IP % n112! Basis function values & derivatives at the integration point:113!--------------------------------------------------------------114stat = ElementInfo( Element, Nodes, IP % U(t), IP % V(t), &115IP % W(t), detJ, Basis, dBasisdx )116117! The source term at the integration point:118!------------------------------------------119LoadAtIP = SUM( Basis(1:n) * LOAD(1:n) )120121! Finally, the elemental matrix & vector:122!----------------------------------------123STIFF(1:n,1:n) = STIFF(1:n,1:n) + IP % s(t) * DetJ * &124MATMUL( dBasisdx, TRANSPOSE( dBasisdx ) )125FORCE(1:n) = FORCE(1:n) + IP % s(t) * DetJ * LoadAtIP * Basis(1:n)126END DO127!------------------------------------------------------------------------------128END SUBROUTINE LocalMatrix129!------------------------------------------------------------------------------130END SUBROUTINE PoissonSolver131!------------------------------------------------------------------------------132133134