70 INTEGER :: i,j,k,n,l,t,k1,k2,iter,Ndeg,istat,nproc,tlen,nthreads
71 CHARACTER(LEN=MAX_STRING_LEN) :: threads
73 REAL(KIND=dp) :: s,dt,dtfunc
74 REAL(KIND=dP),
POINTER :: WorkA(:,:,:) => NULL()
75 REAL(KIND=dp),
POINTER,
SAVE :: sTime(:), sStep(:), sInterval(:), sSize(:), &
76 steadyIt(:),nonlinIt(:),sPrevSizes(:,:),sPeriodic(:)
78 TYPE(element_t
),
POINTER :: CurrentElement
80 LOGICAL :: GotIt,Transient,Scanning,LastSaved
82 INTEGER :: TimeIntervals,interval,timestep, &
83 TotalTimesteps,SavedSteps,CoupledMaxIter,CoupledMinIter
85 INTEGER,
POINTER,
SAVE :: Timesteps(:),OutputIntervals(:), ActiveSolvers(:)
86 REAL(KIND=dp),
POINTER,
SAVE :: TimestepSizes(:,:)
88 INTEGER(KIND=AddrInt) :: ControlProcedure
90 LOGICAL :: InitDirichlet, ExecThis
92 TYPE(elementtype_t
),
POINTER :: elmt
94 TYPE(parenv_t
),
POINTER :: ParallelEnv
96 CHARACTER(LEN=MAX_NAME_LEN) :: ModelName, eq, ExecCommand
97 CHARACTER(LEN=MAX_STRING_LEN) :: OutputFile, PostFile, RestartFile, &
98 OutputName=
' ',PostName=
' ', When, OptionString
100 TYPE(variable_t
),
POINTER :: Var
101 TYPE(mesh_t
),
POINTER :: Mesh
102 TYPE(solver_t
),
POINTER :: Solver
104 REAL(KIND=dp) :: CT0,RT0,tt
106 LOGICAL :: FirstLoad = .TRUE., FirstTime=.TRUE., Found
107 LOGICAL :: Silent, Version, GotModelName
111 INTEGER :: ExtrudeLevels
112 TYPE(mesh_t
),
POINTER :: ExtrudedMesh
114 INTEGER :: omp_get_max_threads
115 INTEGER :: MyVerbosity = 1
120 SUBROUTINE trilinoscleanup() BIND(C,name='TrilinosCleanup')
122 END SUBROUTINE trilinoscleanup
136 TYPE(solver_t
),
POINTER :: abc(:), psolver
137 CHARACTER(LEN=MAX_NAME_LEN) :: str
138 INTEGER :: i,j,j2,j3,k,n
139 TYPE(valuelist_t
),
POINTER :: params
140 LOGICAL :: gotit, vtuformat
142 str = listgetstring( currentmodel % Simulation,
'Post File',gotit)
143 IF(.NOT. gotit)
RETURN
144 k = index( str,
'.vtu' )
145 vtuformat = ( k /= 0 )
147 IF(.NOT. vtuformat )
RETURN
149 CALL info(
'AddVtuOutputSolverHack',
'Adding ResultOutputSolver to write VTU output in file: '&
152 CALL listremove( currentmodel % Simulation,
'Post File')
153 n = currentmodel % NumberOfSolvers+1
157 IF(
ALLOCATED( currentmodel % Solvers(i) % Def_Dofs ) )
THEN
158 j =
SIZE(currentmodel % Solvers(i) % Def_Dofs,1)
159 j2 =
SIZE(currentmodel % Solvers(i) % Def_Dofs,2)
160 j3 =
SIZE(currentmodel % Solvers(i) % Def_Dofs,3)
161 ALLOCATE( abc(i) % Def_Dofs(j,j2,j3) )
165 abc(i) = currentmodel % Solvers(i)
168 nullify( currentmodel % Solvers(i) % ActiveElements )
169 nullify( currentmodel % Solvers(i) % Values )
170 nullify( currentmodel % Solvers(i) % Mesh )
171 nullify( currentmodel % Solvers(i) % BlockMatrix )
172 nullify( currentmodel % Solvers(i) % Matrix )
173 nullify( currentmodel % Solvers(i) % Variable )
177 DEALLOCATE( currentmodel % Solvers )
178 currentmodel % Solvers => abc
179 currentmodel % NumberOfSolvers = n
182 nullify( currentmodel % Solvers(n) % Values )
183 currentmodel % Solvers(n) % PROCEDURE = 0
184 nullify( currentmodel % Solvers(n) % Matrix )
185 nullify( currentmodel % Solvers(n) % BlockMatrix )
186 nullify( currentmodel % Solvers(n) % Values )
187 nullify( currentmodel % Solvers(n) % Variable )
188 nullify( currentmodel % Solvers(n) % ActiveElements )
189 currentmodel % Solvers(n) % NumberOfActiveElements = 0
190 nullify( currentmodel % Solvers(n) % Values )
191 j = currentmodel % NumberOfBodies
192 ALLOCATE( currentmodel % Solvers(n) % Def_Dofs(10,j,6))
193 currentmodel % Solvers(n) % Def_Dofs(:,1:j,6) = -1
196 CALL listaddstring(currentmodel % Solvers(n) % Values,&
197 'Procedure',
'ResultOutputSolve ResultOutputSolver',.false.)
198 CALL listaddstring(currentmodel % Solvers(n) % Values,
'Output Format',
'vtu')
199 CALL listaddstring(currentmodel % Solvers(n) % Values,
'Output File Name',str(1:k-1))
200 CALL listaddstring(currentmodel % Solvers(n) % Values,
'Exec Solver',
'after saving')
201 CALL listaddstring(currentmodel % Solvers(n) % Values,
'Equation',
'InternalVtuOutputSolver')
202 CALL listaddlogical(currentmodel % Solvers(n) % Values,
'Save Geometry IDs',.true.)
212 INTEGER :: i,j,k,nlen
213 LOGICAL :: initsolver, found
220 DO i=1,currentmodel % NumberOfSolvers
222 eq = listgetstring( currentmodel % Solvers(i) % Values,
'Equation', found )
226 DO j=1,currentmodel % NumberOFEquations
227 activesolvers => listgetintegerarray( currentmodel % Equations(j) % Values, &
228 'Active Solvers', found )
230 DO k=1,
SIZE(activesolvers)
231 IF ( activesolvers(k) == i )
THEN
232 CALL listaddlogical( currentmodel % Equations(j) % Values, eq(1:nlen), .true. )
241 DO i=1,currentmodel % NumberOfSolvers
242 eq = listgetstring( currentmodel % Solvers(i) % Values,
'Equation', found )
244 solver => currentmodel % Solvers(i)
245 initsolver = listgetlogical( solver % Values,
'Initialize', found )
246 IF ( found .AND. initsolver )
THEN
247 CALL freematrix( solver % Matrix )
248 CALL listaddlogical( solver % Values,
'Initialize', .false. )
251 IF ( solver % PROCEDURE == 0 .OR. initsolver )
THEN
252 IF ( .NOT.
ASSOCIATED( solver % Mesh ) )
THEN
253 solver % Mesh => currentmodel % Meshes
255 currentmodel % Solver => solver
256 CALL addequationbasics( solver, eq, transient )
257 CALL addequationsolution( solver, transient )
270 TYPE(variable_t
),
POINTER :: dtvar
274 mesh => currentmodel % Meshes
275 DO WHILE(
ASSOCIATED( mesh ) )
276 CALL variableadd( mesh % Variables, mesh,solver, &
277 'Coordinate 1',1,mesh % Nodes % x )
279 CALL variableadd(mesh % Variables,mesh,solver, &
280 'Coordinate 2',1,mesh % Nodes % y )
282 CALL variableadd(mesh % Variables,mesh,solver, &
283 'Coordinate 3',1,mesh % Nodes % z )
285 CALL variableadd( mesh % Variables, mesh, solver,
'Time', 1, stime )
286 CALL variableadd( mesh % Variables, mesh, solver,
'Periodic Time', 1, speriodic )
287 CALL variableadd( mesh % Variables, mesh, solver,
'Timestep', 1, sstep )
288 CALL variableadd( mesh % Variables, mesh, solver,
'Timestep size', 1, ssize )
289 CALL variableadd( mesh % Variables, mesh, solver,
'Timestep interval', 1, sinterval )
292 dtvar => variableget( mesh % Variables,
'Timestep size' )
293 dtvar % PrevValues => sprevsizes
295 CALL variableadd( mesh % Variables, mesh, solver, &
296 'nonlin iter', 1, nonlinit )
297 CALL variableadd( mesh % Variables, mesh, solver, &
298 'coupled iter', 1, steadyit )
313 CHARACTER(LEN=MAX_NAME_LEN) :: str
315 TYPE(solver_t
),
POINTER :: solver
316 INTEGER,
ALLOCATABLE :: indexes(:)
317 REAL(KIND=dp),
ALLOCATABLE :: work(:)
319 INTEGER :: i,j,k,l,m,vect_dof,real_dof,dim
321 REAL(KIND=dp) :: nrm(3),t1(3),t2(3),vec(3),tmp(3),udot
322 TYPE(valuelist_t
),
POINTER :: bc
323 TYPE(nodes_t
),
SAVE :: nodes
324 LOGICAL :: nt_boundary
325 TYPE(element_t
),
POINTER :: element
326 TYPE(variable_t
),
POINTER :: var, vect_var
328 dim = coordinatesystemdimension()
330 IF (getlogical(getsimulation(),
'Restart Before Initial Conditions',found))
THEN
342 initdirichlet = listgetlogical( currentmodel % Simulation, &
343 'Initialize Dirichlet Conditions', gotit )
344 IF ( .NOT. gotit ) initdirichlet = .true.
347 IF ( initdirichlet )
THEN
348 mesh => currentmodel % Meshes
349 DO WHILE(
ASSOCIATED(mesh) )
350 ALLOCATE( work(mesh % MaxElementDOFs) )
351 CALL setcurrentmesh( currentmodel, mesh )
353 DO t = mesh % NumberOfBulkElements + 1, &
354 mesh % NumberOfBulkElements + mesh % NumberOfBoundaryElements
356 element => mesh % Elements(t)
361 currentmodel % CurrentElement => element
362 n = element % TYPE % NumberOfNodes
366 var => mesh % Variables
367 DO WHILE(
ASSOCIATED(var) )
368 solver => var % Solver
369 IF ( .NOT.
ASSOCIATED(solver) ) solver => currentmodel % Solver
371 str = listgetstring( solver % Values,
'Namespace', found )
372 IF (found) CALL listsetnamespace(trim(str))
375 IF ( var % DOFs <= 1 )
THEN
376 work(1:n) = getreal( bc,var % Name, gotit )
379 nt_boundary = .false.
380 IF ( getelementfamily() /= 1 )
THEN
381 k = len_trim(var % name)
382 vect_dof = ichar(var % Name(k:k))-ichar(
'0');
383 IF ( vect_dof>=1 .AND. vect_dof<= 3 )
THEN
384 nt_boundary = getlogical( bc, &
385 'normal-tangential '//var % name(1:k-2), gotit)
387 IF ( nt_boundary )
THEN
388 nt_boundary = .false.
389 vect_var => mesh % Variables
390 DO WHILE(
ASSOCIATED(vect_var) )
391 IF ( vect_var % Dofs>=dim )
THEN
392 DO real_dof=1,vect_var % Dofs
393 nt_boundary =
ASSOCIATED(var % Values, &
394 vect_var % Values(real_dof::vect_var % Dofs))
395 IF ( nt_boundary )
EXIT
397 IF ( nt_boundary )
EXIT
399 vect_var => vect_var % Next
403 IF ( nt_boundary )
THEN
404 CALL getelementnodes(nodes)
405 nrm = normalvector(element,nodes,0._dp,0._dp,.true.)
406 SELECT CASE(element % TYPE % DIMENSION)
411 CALL tangentdirections(nrm,t1,t2)
414 SELECT CASE(vect_dof)
427 k = element % NodeIndexes(j)
428 IF (
ASSOCIATED(var % Perm) ) k = var % Perm(k)
430 IF ( nt_boundary )
THEN
432 m = l+real_dof-vect_dof
433 tmp(l)=vect_var % Values(vect_var % Dofs*(k-1)+m)
435 udot = sum(vec(1:dim)*tmp(1:dim))
436 tmp(1:dim)=tmp(1:dim)+(work(j)-udot)*vec(1:dim)
438 m = l+real_dof-vect_dof
439 vect_var % Values(vect_var % Dofs*(k-1)+m)=tmp(l)
442 var % Values(k) = work(j)
448 IF ( transient .AND. solver % TimeOrder==2 )
THEN
449 work(1:n) = getreal( bc, trim(var % Name) //
' Velocity', gotit )
452 k = element % NodeIndexes(j)
453 IF (
ASSOCIATED(var % Perm) ) k = var % Perm(k)
454 IF ( k>0 ) var % PrevValues(k,1) = work(j)
457 work(1:n) = getreal( bc, trim(var % Name) //
' Acceleration', gotit )
460 k = element % NodeIndexes(j)
461 IF (
ASSOCIATED(var % Perm) ) k = var % Perm(k)
462 IF ( k>0 ) var % PrevValues(k,2) = work(j)
467 CALL listgetrealarray( bc, &
468 var % Name, worka, n, element % NodeIndexes, gotit )
471 k = element % NodeIndexes(j)
472 DO l=1,min(
SIZE(worka,1),var % DOFs)
473 IF (
ASSOCIATED(var % Perm) ) k = var % Perm(k)
474 IF ( k>0 ) var % Values(var % DOFs*(k-1)+l) = worka(l,1,j)
481 CALL listsetnamespace(
'')
498 TYPE(element_t
),
POINTER :: edge
499 INTEGER :: dofs,i,j,k,l
500 CHARACTER(LEN=MAX_NAME_LEN) :: str
501 LOGICAL :: found, thingstodo
502 TYPE(solver_t
),
POINTER :: solver
503 INTEGER,
ALLOCATABLE :: indexes(:)
505 REAL(KIND=dp),
ALLOCATABLE :: work(:)
506 TYPE(valuelist_t
),
POINTER :: ic
509 mesh => currentmodel % Meshes
510 DO WHILE(
ASSOCIATED( mesh ) )
511 ALLOCATE( indexes(mesh % MaxElementDOFs), work(mesh % MaxElementDOFs) )
512 CALL setcurrentmesh( currentmodel, mesh )
516 DO j=1,currentmodel % NumberOfICs
518 ic => currentmodel % ICs(j) % Values
520 var => mesh % Variables
521 DO WHILE(
ASSOCIATED(var) )
523 solver => var % Solver
524 IF ( .NOT.
ASSOCIATED(solver) ) solver => currentmodel % Solver
526 str = listgetstring( solver % Values,
'Namespace', found )
527 IF (found) CALL listsetnamespace(trim(str))
530 IF(
SIZE( var % Values ) == var % DOFs )
THEN
531 val = listgetcreal( ic, var % Name, gotit )
533 WRITE( message,
'(A,ES12.3)')
'Initializing global variable: > '&
534 //trim(var % Name)//
' < to :',val
535 CALL info(
'InitCond', message,level=8)
539 thingstodo = thingstodo .OR. &
540 listcheckpresent( ic, trim(var % Name) )
541 thingstodo = thingstodo .OR. &
542 listcheckpresent( ic, trim(var % Name)//
' Velocity' )
543 thingstodo = thingstodo .OR. &
544 listcheckpresent( ic, trim(var % Name)//
' Acceleration' )
545 thingstodo = thingstodo .OR. &
546 listcheckpresent( ic, trim(var % Name)//
' {e}' )
554 IF( thingstodo )
THEN
555 DO t=1, mesh % NumberOfBulkElements+mesh % NumberOfBoundaryElements
557 currentelement => mesh % Elements(t)
559 i = currentelement % BodyId
562 j = listgetinteger(currentmodel % Bodies(i) % Values, &
563 'Initial Condition',gotit, 1, currentmodel % NumberOfICs )
564 IF ( .NOT. gotit ) cycle
566 ic => currentmodel % ICs(j) % Values
567 currentmodel % CurrentElement => currentelement
568 n = getelementnofnodes()
570 var => mesh % Variables
571 DO WHILE(
ASSOCIATED(var) )
574 solver => var % Solver
575 IF ( .NOT.
ASSOCIATED(solver) ) solver => currentmodel % Solver
577 str = listgetstring( solver % Values,
'Namespace', found )
578 IF (found) CALL listsetnamespace(trim(str))
581 IF(
SIZE( var % Values ) == var % DOFs )
THEN
584 ELSE IF ( var % DOFs <= 1 )
THEN
586 work(1:n) = getreal( ic, var % Name, gotit )
588 dofs = getelementdofs( indexes, usolver=var % Solver )
591 IF (
ASSOCIATED(var % Perm) ) k1 = var % Perm(k1)
592 IF ( k1>0 ) var % Values(k1) = work(k)
596 IF ( transient .AND. solver % TimeOrder==2 )
THEN
597 work(1:n) = getreal( ic, trim(var % Name) //
' Velocity', gotit )
599 dofs = getelementdofs( indexes, usolver=var % Solver )
602 IF (
ASSOCIATED(var % Perm) ) k1 = var % Perm(k1)
603 IF ( k1>0 ) var % PrevValues(k1,1) = work(k)
606 work(1:n) = getreal( ic, trim(var % Name) //
' Acceleration', gotit )
608 dofs = getelementdofs( indexes, usolver=var % Solver )
611 IF (
ASSOCIATED(var % Perm) ) k1 = var % Perm(k1)
612 IF ( k1>0 ) var % PrevValues(k1,2) = work(k)
617 IF(
ASSOCIATED(mesh % Edges))
THEN
618 IF ( i<=mesh % NumberOfBulkElements)
THEN
619 gotit = listcheckpresent( ic, trim(var % Name)//
' {e}' )
621 DO k=1,currentelement % TYPE % NumberOfedges
622 edge => mesh % Edges(currentelement % EdgeIndexes(k))
623 l = var % Perm(currentelement % EdgeIndexes(k)+mesh % NumberOfNodes)
625 CALL localbcintegral( ic, &
626 edge, edge % TYPE % NumberOfNodes, currentelement, n, &
627 trim(var % Name)//
' {e}', work(1) )
628 var % Values(l) = work(1)
636 CALL listgetrealarray( ic, &
637 var % Name, worka, n, currentelement % NodeIndexes, gotit )
642 DO l=1,min(
SIZE(worka,1),var % DOFs)
643 IF (
ASSOCIATED(var % Perm) ) k1 = var % Perm(k1)
644 IF ( k1>0 ) var % Values(var % DOFs*(k1-1)+l) = worka(l,1,k)
649 CALL listsetnamespace(
'')
655 DEALLOCATE( indexes, work )
670 INTEGER :: k,starttime
674 restartfile = listgetstring( currentmodel % Simulation, &
675 'Restart File', gotit )
678 k = listgetinteger( currentmodel % Simulation,
'Restart Position',gotit, &
681 mesh => currentmodel % Meshes
682 DO WHILE(
ASSOCIATED(mesh) )
684 IF ( len_trim(mesh % Name) > 0 )
THEN
685 outputname = trim(mesh % Name) //
'/' // trim(restartfile)
687 outputname = trim(restartfile)
689 IF ( parenv % PEs > 1 ) &
690 outputname = trim(outputname) //
'.' // trim(i2s(parenv % MyPe))
692 CALL setcurrentmesh( currentmodel, mesh )
693 CALL loadrestartfile( outputname,k,mesh )
695 starttime = listgetconstreal( currentmodel % Simulation,
'Restart Time',gotit)
697 var => variableget( mesh % Variables,
'Time' )
698 IF (
ASSOCIATED( var ) ) var % Values(1) = starttime
716 coupledmaxiter, outputintervals, transient, scanning)
717 INTEGER :: timeintervals,coupledminiter, coupledmaxiter,outputintervals(:)
718 LOGICAL :: transient,scanning
720 INTEGER :: interval, timestep, i, j, k, n
721 REAL(KIND=dp) :: dt, ddt, dtfunc
722 INTEGER :: timeleft,cum_timestep
723 INTEGER,
SAVE :: stepcount=0, realtimestep
724 LOGICAL :: execthis,steadystatereached=.false.
726 REAL(KIND=dp) :: cumtime, maxerr, adaptivelimit, &
727 adaptivemintimestep, adaptivemaxtimestep, timeperiod
728 INTEGER :: smallestcount, adaptivekeepsmallest, stepcontrol=-1
729 LOGICAL :: adaptivetime = .true.
731 TYPE(solver_t
),
POINTER :: solver
734 REAL(KIND=dp) :: newtime, prevtime=0, maxtime, exitcond
735 REAL(KIND=dp),
ALLOCATABLE :: xx(:,:), xxnrm(:), yynrm(:), prevxx(:,:,:)
740 TYPE(valuelist_t
),
POINTER :: solverparams
741 TYPE(variable_t
),
POINTER :: stresssol
742 REAL(KIND=dp),
POINTER :: displacement(:)
743 CHARACTER(LEN=MAX_NAME_LEN) :: equation
744 INTEGER :: boundaryelementcount, elementcount, t, body_id
745 INTEGER :: bc_id, nelementnodes, nt, nk
746 INTEGER,
POINTER :: index(:), nodeindexes(:), myperm(:)
747 TYPE(element_t
),
POINTER :: element, currentelement
748 TYPE(nodes_t
) :: elementnodes
749 TYPE(mesh_t
),
POINTER :: mesh
757 IF (myverbosity > 3)
WRITE(*,*)
'NumberOfSolvers = ',&
758 currentmodel % NumberOfSolvers
760 DO i=1,currentmodel % NumberOfSolvers
761 solver => currentmodel % Solvers(i)
762 IF ( solver % PROCEDURE==0 ) cycle
763 IF ( solver % SolverExecWhen == solver_exec_ahead_all )
THEN
764 IF (myverbosity > 3)
WRITE(*,*) &
765 'Calling SolverActivate for Solver', i
766 CALL solveractivate( currentmodel,solver,dt,transient )
770 DO interval = 1, timeintervals
771 stepcount = stepcount + timesteps(interval)
776 DO interval = 1,timeintervals
779 IF ( transient .OR. scanning )
THEN
780 dt = timestepsizes(interval,1)
787 timeperiod = listgetcreal(currentmodel % Simulation,
'Time Period',gotit)
788 IF(.NOT.gotit) timeperiod = huge(timeperiod)
792 DO timestep = 1,timesteps(interval)
794 cum_timestep = cum_timestep + 1
795 sstep(1) = cum_timestep
797 dtfunc = listgetconstreal( currentmodel % Simulation, &
798 'Timestep Function', gotit)
800 CALL warn(
'ExecSimulation',
'Obsolite keyword > Timestep Function < , use > Timestep Size < instead')
802 dtfunc = listgetcreal( currentmodel % Simulation, &
803 'Timestep Size', gotit)
805 IF(gotit) dt = dtfunc
808 stime(1) = stime(1) + dt
809 speriodic(1) = stime(1)
810 DO WHILE(speriodic(1) > timeperiod)
811 speriodic(1) = speriodic(1) - timeperiod
815 IF(timestep > 1 .OR. interval > 1)
THEN
816 DO i =
SIZE(sprevsizes,2),2,-1
817 sprevsizes(1,i) = sprevsizes(1,i-1)
819 sprevsizes(1,1) = ssize(1)
823 sinterval(1) = interval
824 IF (.NOT. transient ) steadyit(1) = steadyit(1) + 1
826 IF ( parenv % MyPE == 0 )
THEN
827 CALL info(
'MAIN',
' ', level=3 )
828 CALL info(
'MAIN',
'-------------------------------------', level=3 )
830 IF ( transient .OR. scanning )
THEN
831 WRITE( message, * )
'Time: ',trim(i2s(cum_timestep)),
'/', &
832 trim(i2s(stepcount)), stime(1)
833 CALL info(
'MAIN', message, level=3 )
837 IF( cum_timestep > 1 )
THEN
838 maxtime = listgetconstreal( currentmodel % Simulation,
'Real Time Max',gotit)
840 WRITE( message,
'(A,F8.3)')
'Fraction of real time left: ',&
841 1.0_dp-realtime() / maxtime
843 timeleft = nint((stepcount-(cum_timestep-1))*(newtime-prevtime)/60._dp);
844 IF (timeleft > 120)
THEN
845 WRITE( message, *)
'Estimated time left: ', &
846 trim(i2s(timeleft/60)),
' hours.'
847 ELSE IF(timeleft > 60)
THEN
848 WRITE( message, *)
'Estimated time left: 1 hour ', &
849 trim(i2s(mod(timeleft,60))),
' minutes.'
850 ELSE IF(timeleft >= 1)
THEN
851 WRITE( message, *)
'Estimated time left: ', &
852 trim(i2s(timeleft)),
' minutes.'
854 WRITE( message, *)
'Estimated time left: less than a minute.'
857 CALL info(
'MAIN', message, level=3 )
861 WRITE( message, * )
'Steady state iteration: ',cum_timestep
862 CALL info(
'MAIN', message, level=3 )
865 CALL info(
'MAIN',
'-------------------------------------', level=3 )
866 CALL info(
'MAIN',
' ', level=3 )
872 adaptivetime = listgetlogical( currentmodel % Simulation, &
873 'Adaptive Timestepping', gotit )
875 IF ( transient .AND. adaptivetime )
THEN
876 adaptivelimit = listgetconstreal( currentmodel % Simulation, &
877 'Adaptive Time Error', gotit )
879 IF ( .NOT. gotit )
THEN
880 WRITE( message, * )
'Adaptive Time Limit must be given for' // &
881 'adaptive stepping scheme.'
882 CALL fatal(
'ElmerSolver', message )
885 adaptivemaxtimestep = listgetconstreal( currentmodel % Simulation, &
886 'Adaptive Max Timestep', gotit )
887 IF ( .NOT. gotit ) adaptivemaxtimestep = dt
888 adaptivemaxtimestep = min(adaptivemaxtimestep, dt)
890 adaptivemintimestep = listgetconstreal( currentmodel % Simulation, &
891 'Adaptive Min Timestep', gotit )
893 adaptivekeepsmallest = listgetinteger( currentmodel % Simulation, &
894 'Adaptive Keep Smallest', gotit, minv=0 )
896 n = currentmodel % NumberOfSolvers
900 solver => currentmodel % Solvers(i)
901 IF (
ASSOCIATED( solver % Variable % Values ) )
THEN
902 IF (
ASSOCIATED( solver % Variable % PrevValues ) )
THEN
903 j = max( j,
SIZE( solver % Variable % PrevValues,2 ) )
905 k = max( k,
SIZE( solver % Variable % Values ) )
908 ALLOCATE( xx(n,k), yynrm(n), xxnrm(n), prevxx( n,k,j ) )
911 IF ( ddt == 0.0d0 .OR. ddt > adaptivemaxtimestep ) ddt = adaptivemaxtimestep
915 DO WHILE( cumtime < dt-1.0d-12 )
916 ddt = min( dt - cumtime, ddt )
918 DO i=1,currentmodel % NumberOFSolvers
919 solver => currentmodel % Solvers(i)
920 IF (
ASSOCIATED( solver % Variable % Values ) )
THEN
921 n =
SIZE( solver % Variable % Values )
922 xx(i,1:n) = solver % Variable % Values
923 xxnrm(i) = solver % Variable % Norm
924 IF (
ASSOCIATED( solver % Variable % PrevValues ) )
THEN
925 DO j=1,
SIZE( solver % Variable % PrevValues,2 )
926 prevxx(i,1:n,j) = solver % Variable % PrevValues(:,j)
932 stime(1) = s + cumtime + ddt
934 CALL solveequations( currentmodel, ddt, transient, &
935 coupledminiter, coupledmaxiter, steadystatereached, realtimestep )
938 maxerr = listgetconstreal( currentmodel % Simulation, &
939 'Adaptive Error Measure', gotit )
941 DO i=1,currentmodel % NumberOFSolvers
942 solver => currentmodel % Solvers(i)
943 IF (
ASSOCIATED( solver % Variable % Values ) )
THEN
944 n =
SIZE(solver % Variable % Values)
945 yynrm(i) = solver % Variable % Norm
946 solver % Variable % Values = xx(i,1:n)
947 IF (
ASSOCIATED( solver % Variable % PrevValues ) )
THEN
948 DO j=1,
SIZE( solver % Variable % PrevValues,2 )
949 solver % Variable % PrevValues(:,j) = prevxx(i,1:n,j)
956 stime(1) = s + cumtime + ddt/2
957 CALL solveequations( currentmodel, ddt/2, transient, &
958 coupledminiter, coupledmaxiter, steadystatereached, realtimestep )
959 stime(1) = s + cumtime + ddt
960 CALL solveequations( currentmodel, ddt/2, transient, &
961 coupledminiter, coupledmaxiter, steadystatereached, realtimestep )
963 maxerr = abs( maxerr - listgetconstreal( currentmodel % Simulation, &
964 'Adaptive Error Measure', gotit ) )
966 IF ( .NOT. gotit )
THEN
968 DO i=1,currentmodel % NumberOFSolvers
969 solver => currentmodel % Solvers(i)
970 IF (
ASSOCIATED( solver % Variable % Values ) )
THEN
971 IF ( yynrm(i) /= solver % Variable % Norm )
THEN
972 maxerr = max(maxerr,abs(yynrm(i)-solver % Variable % Norm)/yynrm(i))
978 IF ( maxerr < adaptivelimit .OR. ddt <= adaptivemintimestep )
THEN
979 cumtime = cumtime + ddt
980 realtimestep = realtimestep+1
981 IF ( smallestcount >= adaptivekeepsmallest .OR. stepcontrol > 0 )
THEN
982 ddt = min( 2*ddt, adaptivemaxtimestep )
987 smallestcount = smallestcount + 1
990 DO i=1,currentmodel % NumberOFSolvers
991 solver => currentmodel % Solvers(i)
992 IF (
ASSOCIATED( solver % Variable % Values ) )
THEN
993 n =
SIZE(solver % Variable % Values)
994 solver % Variable % Norm = xxnrm(i)
995 solver % Variable % Values = xx(i,1:n)
996 IF (
ASSOCIATED( solver % Variable % PrevValues ) )
THEN
997 DO j=1,
SIZE( solver % Variable % PrevValues,2 )
998 solver % Variable % PrevValues(:,j) = prevxx(i,1:n,j)
1006 WRITE(*,
'(a,3e20.12)')
'Adaptive(cum,ddt,err): ', cumtime, ddt, maxerr
1011 DEALLOCATE( xx, xxnrm, yynrm, prevxx )
1013 IF( myverbosity > 3)
WRITE(*,*)
'Calling SolveEquations &
1014 (no transient and no adaptive)'
1015 CALL solveequations( currentmodel, dt, transient, &
1016 coupledminiter, coupledmaxiter, steadystatereached, realtimestep )
1017 realtimestep = realtimestep+1
1021 solver => currentmodel % Solvers(2)
1022 solverparams => getsolverparams(solver)
1023 equation = getstring(solverparams,
'Equation', gotit)
1031 IF( outputintervals(interval) /= 0 )
THEN
1034 k = mod( timestep-1, outputintervals(interval) )
1035 IF ( k == 0 .OR. steadystatereached )
THEN
1037 DO i=1,currentmodel % NumberOfSolvers
1038 solver => currentmodel % Solvers(i)
1039 IF ( solver % PROCEDURE == 0 ) cycle
1040 execthis = ( solver % SolverExecWhen == solver_exec_ahead_save)
1041 when = listgetstring( solver % Values,
'Exec Solver', gotit )
1042 IF ( gotit ) execthis = ( when ==
'before saving')
1043 IF( execthis ) CALL solveractivate( currentmodel,solver,dt,transient )
1049 DO i=1,currentmodel % NumberOfSolvers
1050 solver => currentmodel % Solvers(i)
1051 IF ( solver % PROCEDURE == 0 ) cycle
1052 execthis = ( solver % SolverExecWhen == solver_exec_after_save)
1053 when = listgetstring( solver % Values,
'Exec Solver', gotit )
1054 IF ( gotit ) execthis = ( when ==
'after saving')
1055 IF( execthis ) CALL solveractivate( currentmodel,solver,dt,transient )
1061 maxtime = listgetcreal( currentmodel % Simulation,
'Real Time Max',gotit)
1062 IF( gotit .AND. realtime() - rt0 > maxtime )
THEN
1063 CALL info(
'ElmerSolver',
'Reached allowed maximum real time, exiting...')
1067 exitcond = listgetcreal( currentmodel % Simulation,
'Exit Condition',gotit)
1068 IF( gotit .AND. exitcond > 0.0_dp )
THEN
1069 CALL info(
'ElmerSolver',
'Found a positive exit condition, exiting...')
1075 IF ( steadystatereached .AND. .NOT. (transient .OR. scanning) )
THEN
1076 IF ( timestep >= coupledminiter )
EXIT
1087 100
DO i=1,currentmodel % NumberOfSolvers
1088 solver => currentmodel % Solvers(i)
1089 IF ( solver % PROCEDURE == 0 ) cycle
1090 when = listgetstring( solver % Values,
'Exec Solver', gotit )
1092 IF ( when ==
'after simulation' .OR. when ==
'after all' )
THEN
1093 CALL solveractivate( currentmodel,solver,dt,transient )
1094 IF (
ASSOCIATED(solver % Variable % Values) ) lastsaved = .false.
1097 IF ( solver % SolverExecWhen == solver_exec_after_all )
THEN
1098 CALL solveractivate( currentmodel,solver,dt,transient )
1099 IF (
ASSOCIATED(solver % Variable % Values) ) lastsaved = .false.
1104 IF( .NOT. lastsaved )
THEN
1105 DO i=1,currentmodel % NumberOfSolvers
1106 solver => currentmodel % Solvers(i)
1107 IF ( solver % PROCEDURE == 0 ) cycle
1108 execthis = ( solver % SolverExecWhen == solver_exec_ahead_save)
1109 when = listgetstring( solver % Values,
'Exec Solver', gotit )
1110 IF ( gotit ) execthis = ( when ==
'before saving')
1111 IF( execthis ) CALL solveractivate( currentmodel,solver,dt,transient )
1125 INTEGER :: i, j,k,l,n,q,currentstep,nlen
1126 TYPE(variable_t
),
POINTER :: var
1127 LOGICAL :: eiganal, gotit
1128 CHARACTER(LEN=MAX_NAME_LEN) :: simul
1129 LOGICAL :: binaryoutput, saveall
1131 simul = listgetstring( currentmodel % Simulation,
'Simulation Type' )
1133 outputfile = listgetstring(currentmodel % Simulation,
'Output File',gotit)
1135 IF ( parenv % PEs > 1 )
THEN
1137 IF ( outputfile(i:i) ==
' ' )
EXIT
1139 outputfile(i:i) =
'.'
1140 WRITE( outputfile(i+1:),
'(a)' ) trim(i2s(parenv % MyPE))
1143 binaryoutput = listgetlogical( currentmodel % Simulation,
'Binary Output',gotit )
1144 IF ( .NOT.gotit ) binaryoutput = .false.
1146 saveall = .NOT.listgetlogical( currentmodel % Simulation,&
1147 'Omit unchanged variables in output',gotit )
1148 IF ( .NOT.gotit ) saveall = .true.
1150 mesh => currentmodel % Meshes
1151 DO WHILE(
ASSOCIATED( mesh ) )
1152 IF ( mesh % OutputActive )
THEN
1153 nlen = len_trim(mesh % Name )
1154 IF ( nlen > 0 )
THEN
1155 outputname = mesh % Name(1:nlen) //
'/' // trim(outputfile)
1157 outputname = outputfile
1161 DO i=1,currentmodel % NumberOfSolvers
1162 IF (
ASSOCIATED( currentmodel % Solvers(i) % Mesh, mesh ) )
THEN
1163 eiganal = listgetlogical( currentmodel % Solvers(i) % Values, &
1164 'Eigen Analysis', gotit )
1165 eiganal = eiganal .OR. listgetlogical( currentmodel % Solvers(i) % Values, &
1166 'Harmonic Analysis', gotit )
1169 var => currentmodel % Solvers(i) % Variable
1170 IF (
ASSOCIATED(var % EigenValues) )
THEN
1171 IF ( totaltimesteps == 1 )
THEN
1172 DO j=1,currentmodel % Solvers(i) % NOFEigenValues
1173 IF ( currentmodel % Solvers(i) % Matrix % COMPLEX )
THEN
1175 n =
SIZE(var % Values)/var % DOFs
1178 q = var % DOFs*(k-1)
1179 var % Values(q+l) =
REAL(var % eigenvectors(j,q/2+l))
1180 var % Values(q+l+var % DOFs/2) = aimag(var % EigenVectors(j,q/2+l))
1184 var % Values =
REAL( Var % EigenVectors(j,:) )
1186 savedsteps = saveresult( outputname, mesh, &
1187 j, stime(1), binaryoutput, saveall )
1190 j = min( currentstep,
SIZE( var % EigenVectors,1 ) )
1191 IF ( currentmodel % Solvers(i) % Matrix % COMPLEX )
THEN
1192 n =
SIZE(var % Values)/var % DOFs
1195 q = var % DOFs*(k-1)
1196 var % Values(q+l) =
REAL(var % eigenvectors(j,q/2+l))
1197 var % Values(q+l+var % DOFs/2) = aimag(var % EigenVectors(j,q/2+l))
1201 var % Values =
REAL(var % eigenvectors(j,:))
1203 savedsteps = saveresult( outputname, mesh, &
1204 currentstep, stime(1), binaryoutput, saveall )
1206 var % Values = 0.0d0
1212 IF ( .NOT. eiganal )
THEN
1213 savedsteps = saveresult( outputname,mesh, nint(sstep(1)), &
1214 stime(1), binaryoutput, saveall )
1220 mesh => currentmodel % Meshes
1221 DO WHILE(
ASSOCIATED( mesh ) )
1222 IF ( mesh % OutputActive ) &
1223 mesh % SavesDone=mesh % SavesDone+1
1237 TYPE(variable_t
),
POINTER :: var
1238 LOGICAL :: eiganal = .false., found
1239 INTEGER :: i, j,k,l,n,q,currentstep,nlen,timesteps,savedeigenvalues
1240 CHARACTER(LEN=MAX_NAME_LEN) :: simul, savewhich
1242 simul = listgetstring( currentmodel % Simulation,
'Simulation Type' )
1244 outputfile = listgetstring( currentmodel % Simulation,
'Output File',gotit )
1246 IF ( parenv % PEs > 1 )
THEN
1248 IF ( outputfile(i:i) ==
' ' )
EXIT
1250 outputfile(i:i) =
'.'
1251 WRITE( outputfile(i+1:),
'(a)' ) trim(i2s(parenv % MyPE))
1255 postfile = listgetstring( currentmodel % Simulation,
'Post File',gotit )
1256 IF( .NOT. gotit )
RETURN
1258 IF ( parenv % PEs > 1 )
THEN
1260 IF ( postfile(i:i) ==
' ' )
EXIT
1263 WRITE( postfile(i+1:),
'(a)' ) trim(i2s(parenv % MyPE))
1268 mesh => currentmodel % Meshes
1269 DO WHILE(
ASSOCIATED( mesh ) )
1270 IF ( currentstep == 0 .AND. mesh % SavesDone > 0)
THEN
1277 IF ( mesh % OutputActive )
THEN
1278 nlen = len_trim(mesh % Name)
1279 IF ( nlen==0 .OR. filenamequalified(outputfile) )
THEN
1280 outputname = outputfile
1282 outputname = mesh % Name(1:nlen)//
'/'//trim(outputfile)
1285 IF ( nlen==0 .OR. filenamequalified(postfile) )
THEN
1288 postname = mesh % Name(1:nlen)//
'/'//trim(postfile)
1291 IF ( listgetlogical( currentmodel % Simulation,
'Filename Numbering',gotit) )
THEN
1292 IF( currentstep == 0 )
THEN
1293 postname = nextfreefilename(postname)
1295 postname = nextfreefilename(postname,lastexisting = .true. )
1300 CALL setcurrentmesh( currentmodel, mesh )
1305 timesteps = totaltimesteps
1306 DO i=1,currentmodel % NumberOfSolvers
1307 IF (
ASSOCIATED(currentmodel % Solvers(i) % Mesh, mesh))
THEN
1308 eiganal = listgetlogical( currentmodel % &
1309 solvers(i) % Values,
'Eigen Analysis', gotit )
1311 eiganal = eiganal .OR. listgetlogical( currentmodel % &
1312 solvers(i) % Values,
'Harmonic Analysis', gotit )
1314 IF ( eiganal ) timesteps = max( timesteps, &
1315 currentmodel % Solvers(i) % NOFEigenValues )
1319 DO i=1,currentmodel % NumberOfSolvers
1320 IF (
ASSOCIATED(currentmodel % Solvers(i) % Mesh, mesh))
THEN
1321 eiganal = listgetlogical( currentmodel % &
1322 solvers(i) % Values,
'Eigen Analysis', gotit )
1324 eiganal = eiganal .OR. listgetlogical( currentmodel % &
1325 solvers(i) % Values,
'Harmonic Analysis', gotit )
1328 savewhich = listgetstring( currentmodel % Solvers(i) % Values, &
1329 'Eigen and Harmonic Solution Output', found )
1331 savedeigenvalues = currentmodel % Solvers(i) % NOFEigenValues
1332 IF( totaltimesteps > 1 )
THEN
1336 DO j=1, savedeigenvalues
1337 var => mesh % Variables
1338 DO WHILE(
ASSOCIATED(var))
1339 IF ( .NOT.
ASSOCIATED(var % EigenValues) )
THEN
1344 IF ( currentmodel % Solvers(i) % Matrix % COMPLEX )
THEN
1345 IF(var % DOFs==1)
THEN
1350 n =
SIZE(var % Values)/var % DOFs
1353 q = var % DOFs*(k-1)
1354 var % Values(q+l) =
REAL(var % eigenvectors(j,q/2+l))
1355 var % Values(q+l+var % DOFs/2) = aimag(var % EigenVectors(j,q/2+l))
1360 SELECT CASE( savewhich )
1362 var % Values = var % EigenVectors(j,:)
1364 var % Values = aimag(var % EigenVectors(j,:))
1366 var % Values = abs(var % EigenVectors(j,:))
1368 var % Values = atan2(aimag(var % EigenVectors(j,:)), &
1369 REAL(var % eigenvectors(j,:)))
1371 var % CValues => var % EigenVectors(j,:)
1377 IF ( currentstep > 0 )
THEN
1378 IF ( mesh % SavesDone /= 0 )
THEN
1379 IF( totaltimesteps == 1 )
THEN
1380 mesh % SavesDone = j
1382 mesh % SavesDone = currentstep
1385 CALL writepostfile( postname,outputname, currentmodel, &
1386 currentmodel % Solvers(i) % NOFEigenValues, .true. )
1396 IF ( .NOT. eiganal .OR. currentstep == 0 )
THEN
1397 WRITE(6,*)
'timesteps = ', timesteps
1398 CALL writepostfile( postname, outputname, currentmodel, timesteps, .true. )
1401 var => mesh % Variables
1402 DO WHILE(
ASSOCIATED(var))
1403 IF (
ASSOCIATED(var % EigenValues) )
THEN
1404 var % Values = 0._dp
1405 var % CValues => null()
1558 CHARACTER(LEN=*) :: modelname
1559 LOGICAL :: boundariesonly
1561 INTEGER,
OPTIONAL :: numprocs,mype
1563 TYPE(model_t
),
POINTER :: model
1566 TYPE(mesh_t
),
POINTER :: mesh,mesh1,newmesh,oldmesh
1567 INTEGER :: i,j,k,l,s,nlen,eqn,meshkeep,meshlevels
1568 LOGICAL :: gotit,gotmesh,found,onemeshname, openfile, transient
1569 LOGICAL :: stat, single, meshgrading, newloadmesh
1570 TYPE(solver_t
),
POINTER :: solver
1571 INTEGER(KIND=AddrInt) :: initproc
1572 INTEGER,
TARGET :: def_dofs(10,6)
1573 REAL(KIND=dp) :: meshpower
1574 REAL(KIND=dp),
POINTER :: h(:)
1575 CHARACTER(LEN=MAX_NAME_LEN) :: name,elementdef,elementdef0
1576 CHARACTER(LEN=MAX_NAME_LEN) :: meshdir,meshname
1577 TYPE(valuelist_t
),
POINTER :: lst
1578 INTEGER,
ALLOCATABLE :: edgedofs(:),facedofs(:)
1582 currentmodel => model
1583 nullify( model % Variables )
1588 model % DIMENSION = 0
1589 model % NumberOfBoundaries = 0
1590 model % NumberOfBodies = 0
1591 model % NumberOfICs = 0
1592 model % NumberOfBCs = 0
1593 model % NumberOfEquations = 0
1594 model % NumberOfSolvers = 0
1595 model % NumberOfMaterials = 0
1596 model % NumberOfBodyForces = 0
1598 INQUIRE( unit=infileunit, opened=openfile )
1599 IF ( .NOT. openfile )
OPEN( unit=infileunit, file=modelname, status=
'OLD' )
1600 CALL loadinputfile( model,infileunit,modelname,meshdir,meshname, .true., .true. )
1601 rewind( infileunit )
1602 CALL loadinputfile( model,infileunit,modelname,meshdir,meshname, .true., .false. )
1603 IF ( .NOT. openfile )
CLOSE( infileunit )
1607 transient=listgetstring(model % Simulation, &
1608 'Simulation Type',found)==
'transient'
1610 def_dofs = -1; def_dofs(:,1)=1
1613 DO WHILE(i<=model % NumberOFSolvers)
1615 solver => model % Solvers(i)
1616 model % Solver => solver
1618 name = listgetstring( solver % Values,
'Procedure', found )
1620 initproc = getprocaddr( trim(name)//
'_Init0', abort=.false. )
1621 IF ( initproc /= 0 )
THEN
1622 CALL execsolver( initproc, model, solver, &
1623 solver % dt, transient )
1625 solver => model % Solvers(i)
1626 model % Solver => solver
1630 gotmesh = listcheckpresent(solver % Values,
'Mesh')
1632 IF(.NOT.
ALLOCATED(solver % Def_Dofs))
THEN
1633 ALLOCATE(solver % Def_Dofs(10,model % NumberOfBodies,6))
1634 solver % Def_Dofs = -1; solver % Def_Dofs(:,:,1)=1
1639 elementdef = listgetstring( solver % Values,
'Element', stat )
1641 IF ( .NOT. stat )
THEN
1642 IF ( listgetlogical( solver % Values, &
1643 'Discontinuous Galerkin', stat ) )
THEN
1644 solver % Def_Dofs(:,:,4) = 0
1645 IF ( .NOT. gotmesh ) def_dofs(:,4) = max(def_dofs(:,4),0 )
1653 elementdef0 = elementdef
1655 j = index( elementdef0,
'-' )
1657 elementdef = elementdef0(1:j-1)
1659 elementdef = elementdef0
1663 elementdef0 = elementdef0(j+1:)
1674 name = listgetstring( model % Simulation,
'Mesh', gotit )
1676 onemeshname = .false.
1680 nlen = len_trim(name)
1681 DO WHILE( k<=nlen .AND. name(k:k) /=
' ' )
1682 meshdir(i:i) = name(k:k)
1683 meshname(i:i) = name(k:k)
1688 DO WHILE( k<=nlen .AND. name(k:k) ==
' ' )
1695 DO WHILE( name(k:k) /=
' ' )
1696 meshname(i:i) = name(k:k)
1701 onemeshname = .true.
1702 meshdir =
"." // char(0)
1704 meshname(i:i) = char(0)
1707 nullify( model % Meshes )
1708 IF ( meshdir(1:1) /=
' ' )
THEN
1710 CALL resettimer(
'LoadMesh')
1711 newloadmesh = listgetlogical( model % Simulation,
'New Load Mesh',gotit)
1712 IF( .NOT. gotit ) newloadmesh = .true.
1713 IF( newloadmesh )
THEN
1714 model % Meshes => loadmesh2( model, meshdir, meshname, &
1715 boundariesonly, numprocs, mype, def_dofs )
1717 model % Meshes => loadmesh( model, meshdir, meshname, &
1718 boundariesonly, numprocs, mype, def_dofs(1,:) )
1721 CALL checktimer(
'LoadMesh',level=5,delete=.true.)
1723 CALL setcoordinatesystem( model )
1725 meshlevels = listgetinteger( model % Simulation,
'Mesh Levels', gotit )
1726 IF ( .NOT. gotit ) meshlevels=1
1728 meshkeep = listgetinteger( model % Simulation,
'Mesh keep', gotit )
1729 IF ( .NOT. gotit ) meshkeep=meshlevels
1731 meshpower = listgetconstreal( model % Simulation,
'Mesh Grading Power',gotit)
1732 meshgrading = listgetlogical( model % Simulation,
'Mesh Keep Grading', gotit)
1735 oldmesh => model % Meshes
1737 IF (meshgrading)
THEN
1738 ALLOCATE(h(oldmesh % NumberOfNodes))
1739 model % Mesh => oldmesh
1740 CALL getnodalelementsize(model,meshpower,.false.,h)
1741 newmesh => splitmeshequal(oldmesh,h)
1744 newmesh => splitmeshequal(oldmesh)
1747 IF(
ASSOCIATED(oldmesh % Faces))
THEN
1748 CALL findmeshedges(newmesh)
1750 ALLOCATE( edgedofs(newmesh % NumberOfBulkElements))
1751 ALLOCATE( facedofs(newmesh % NumberOfBulkElements))
1752 edgedofs = max(0,maxval(def_dofs(:,2)))
1753 facedofs = max(0,maxval(def_dofs(:,3)))
1754 CALL setmeshedgefacedofs(newmesh,edgedofs,facedofs)
1755 DEALLOCATE(edgedofs,facedofs)
1757 CALL setmeshmaxdofs(newmesh)
1758 IF(parenv % PEs>1) CALL sparedgenumbering(newmesh)
1759 IF(parenv % PEs>1) CALL sparfacenumbering(newmesh)
1762 IF ( i>meshlevels-meshkeep+1 )
THEN
1763 newmesh % Next => oldmesh
1764 newmesh % Parent => oldmesh
1765 oldmesh % Child => newmesh
1766 newmesh % OutputActive = .true.
1767 oldmesh % OutputActive = .false.
1769 CALL releasemesh(oldmesh)
1771 model % Meshes => newmesh
1775 IF ( onemeshname )
THEN
1778 i = len_trim(meshname)
1780 IF (meshname(i:i) /=
'/' )
THEN
1790 model % Meshes % Name =
' '
1791 DO WHILE( meshname(i:i) /= char(0) )
1792 model % Meshes % Name(k:k) = meshname(i:i)
1798 oldmesh => model % Meshes % Parent
1799 DO WHILE(
ASSOCIATED( oldmesh ) )
1800 oldmesh % Name = trim(oldmesh % Child % Name)//
'p'
1801 oldmesh => oldmesh % Parent
1804 DO i=1,model % NumberOfSolvers
1805 model % Solvers(i) % Mesh => model % Meshes
1809 DO s=1,model % NumberOfSolvers
1810 name = listgetstring( model % Solvers(s) % Values,
'Mesh', gotit )
1813 WRITE(message,
'(A,I0)')
'Loading solver specific mesh > '//trim(name)//
' < for solver ',s
1814 CALL info(
'ElmerLoadModel',message,level=7)
1817 IF ( name(1:8) ==
'-single ' )
THEN
1821 onemeshname = .false.
1824 nlen = len_trim(name)
1826 DO WHILE( k<=nlen .AND. name(k:k) /=
' ' )
1827 meshdir(i:i) = name(k:k)
1828 meshname(i:i) = name(k:k)
1833 DO WHILE( k<=nlen .AND. name(k:k) ==
' ' )
1840 DO WHILE( name(k:k) /=
' ' )
1841 meshname(i:i) = name(k:k)
1846 onemeshname = .true.
1847 meshdir =
"." // char(0)
1849 meshname(i:i) = char(0)
1851 IF ( onemeshname )
THEN
1854 DO WHILE( i>0 .AND. meshname(i:i) /=
'/' )
1859 mesh => model % Meshes
1861 DO WHILE(
ASSOCIATED( mesh ) )
1865 DO WHILE( meshname(j:j) /= char(0) )
1866 IF ( mesh % Name(k:k) /= meshname(j:j) )
THEN
1873 IF ( len_trim(mesh % Name) /= k-1 ) found = .false.
1879 model % Solvers(s) % Mesh => mesh
1885 def_dofs(j,i) = maxval(model % Solvers(s) % Def_Dofs(j,:,i))
1889 newloadmesh = listgetlogical( model % Simulation,
'New Load Mesh',gotit)
1890 IF(.NOT. gotit) newloadmesh = .true.
1892 IF( newloadmesh )
THEN
1893 model % Solvers(s) % Mesh => &
1894 loadmesh2( model,meshdir,meshname,boundariesonly,1,0,def_dofs )
1896 model % Solvers(s) % Mesh => &
1897 loadmesh( model,meshdir,meshname,boundariesonly,1,0,def_dofs(1,:) )
1900 IF( newloadmesh )
THEN
1901 model % Solvers(s) % Mesh => &
1902 loadmesh2( model,meshdir,meshname,boundariesonly,numprocs,mype,def_dofs )
1904 model % Solvers(s) % Mesh => &
1905 loadmesh( model,meshdir,meshname,boundariesonly,numprocs,mype,def_dofs(1,:) )
1908 model % Solvers(s) % Mesh % OutputActive = .true.
1911 meshlevels = listgetinteger( model % Solvers(s) % Values,
'Mesh Levels', gotit )
1912 IF ( .NOT. gotit ) meshlevels=1
1914 meshkeep = listgetinteger( model % Solvers(s) % Values,
'Mesh keep', gotit )
1915 IF ( .NOT. gotit ) meshkeep=meshlevels
1917 meshpower = listgetconstreal( model % Simulation,
'Mesh Grading Power',gotit)
1918 meshgrading = listgetlogical( model % Simulation,
'Mesh Keep Grading', gotit)
1922 oldmesh => model % Solvers(s) % Mesh
1924 IF (meshgrading)
THEN
1925 ALLOCATE(h(oldmesh % NumberOfNodes))
1926 model % Mesh => oldmesh
1927 CALL getnodalelementsize(model,meshpower,.false.,h)
1928 newmesh => splitmeshequal(oldmesh,h)
1931 newmesh => splitmeshequal(oldmesh)
1934 IF(
ASSOCIATED(oldmesh % Faces))
THEN
1935 CALL findmeshedges(newmesh)
1937 ALLOCATE( edgedofs(newmesh % NumberOfBulkElements))
1938 ALLOCATE( facedofs(newmesh % NumberOfBulkElements))
1939 edgedofs = max(0,maxval(def_dofs(:,2)))
1940 facedofs = max(0,maxval(def_dofs(:,3)))
1941 CALL setmeshedgefacedofs(newmesh,edgedofs,facedofs)
1942 DEALLOCATE(edgedofs,facedofs)
1944 CALL setmeshmaxdofs(newmesh)
1945 IF(parenv % PEs>1) CALL sparedgenumbering(newmesh)
1946 IF(parenv % PEs>1) CALL sparfacenumbering(newmesh)
1949 IF ( i>meshlevels-meshkeep+1 )
THEN
1950 newmesh % Next => oldmesh
1951 newmesh % Parent => oldmesh
1952 oldmesh % Child => newmesh
1953 newmesh % Name = oldmesh % Name
1954 newmesh % OutputActive = .true.
1955 oldmesh % OutputActive = .false.
1957 CALL releasemesh(oldmesh)
1959 model % Solvers(s) % Mesh => newmesh
1962 IF ( onemeshname ) i = 0
1966 model % Solvers(s) % Mesh % Name =
' '
1967 DO WHILE( meshname(i:i) /= char(0) )
1968 model % Solvers(s) % Mesh % Name(k:k) = meshname(i:i)
1973 IF (
ASSOCIATED( model % Meshes ) )
THEN
1974 mesh1 => model % Meshes
1975 DO WHILE(
ASSOCIATED( mesh1 % Next ) )
1976 mesh1 => mesh1 % Next
1978 mesh1 % Next => model % Solvers(s) % Mesh
1980 model % Meshes => model % Solvers(s) % Mesh
1985 CALL setcoordinatesystem( model )
1987 IF ( outputpath ==
' ' )
THEN
1989 IF ( meshdir(i:i) == char(0) )
EXIT
1990 outputpath(i:i) = meshdir(i:i)
1994 mesh => model % Meshes
1995 DO WHILE(
ASSOCIATED( mesh ) )
1996 CALL meshstabparams( mesh )
2006 CHARACTER(LEN=*) :: elementdef
2008 INTEGER :: ind(8),i,j,n
2009 INTEGER,
POINTER :: gdofs(:,:), sdofs(:,:,:)
2011 ind = [1,2,3,4,5,6,7,8]
2013 IF (elementdef(1:5) ==
'point' ) ind=1
2014 IF (elementdef(1:4) ==
'line' ) ind=2
2015 IF (elementdef(1:3) ==
'tri' ) ind=3
2016 IF (elementdef(1:4) ==
'quad' ) ind=4
2017 IF (elementdef(1:5) ==
'tetra' ) ind=5
2018 IF (elementdef(1:7) ==
'pyramid' ) ind=6
2019 IF (elementdef(1:5) ==
'prism' ) ind=7
2020 IF (elementdef(1:5) ==
'brick' ) ind=8
2021 IF (elementdef(1:8) ==
'tri_face' ) ind=9
2022 IF (elementdef(1:9) ==
'quad_face' ) ind=10
2024 n = index(elementdef,
'-')
2025 IF (n<=0) n=len_trim(elementdef)
2027 j = index( elementdef(1:n),
'n:' )
2029 READ( elementdef(j+2:), * ) l
2030 solver % Def_Dofs(ind,:,1) = l
2031 IF (.NOT. gotmesh ) def_dofs(ind,1) = max(def_dofs(ind,1), l)
2034 j = index( elementdef(1:n),
'e:' )
2036 READ( elementdef(j+2:), * ) l
2037 solver % Def_Dofs(ind,:,2) = l
2038 IF ( .NOT. gotmesh ) def_dofs(ind,2) = max(def_dofs(ind,2), l )
2041 j = index( elementdef(1:n),
'f:' )
2043 READ( elementdef(j+2:), * ) l
2044 solver % Def_Dofs(ind,:,3) = l
2045 IF ( .NOT. gotmesh ) def_dofs(ind,3) = max(def_dofs(ind,3), l )
2048 j = index( elementdef(1:n),
'd:' )
2050 READ( elementdef(j+2:), * ) l
2051 solver % Def_Dofs(ind,:,4) = l
2052 IF ( .NOT. gotmesh ) def_dofs(ind,4) = max(def_dofs(ind,4), l )
2054 IF ( listgetlogical( solver % Values, &
2055 'Discontinuous Galerkin', stat ) )
THEN
2056 solver % Def_Dofs(ind,:,4) = 0
2057 IF ( .NOT. gotmesh ) def_dofs(ind,4) = max(def_dofs(ind,4),0 )
2061 j = index( elementdef(1:n),
'b:' )
2063 READ( elementdef(j+2:), * ) l
2064 solver % Def_Dofs(ind,:,5) = l
2065 IF ( .NOT. gotmesh ) def_dofs(ind,5) = max(def_dofs(ind,5), l )
2068 j = index( elementdef(1:n),
'p:' )
2070 IF ( elementdef(j+2:j+2)==
'%' )
THEN
2071 solver % Def_Dofs(ind,:,6) = 0
2073 READ( elementdef(j+2:), * ) l
2074 solver % Def_Dofs(ind,:,6) = l
2075 IF ( .NOT. gotmesh ) def_dofs(ind,6) = max(def_dofs(ind,6), l )
2089 INTEGER,
POINTER :: outputmask(:)
2092 minoutputlevel = listgetinteger( currentmodel % Simulation, &
2093 'Min Output Level', gotit )
2095 maxoutputlevel = listgetinteger( currentmodel % Simulation, &
2096 'Max Output Level', gotit )
2098 IF ( .NOT. gotit ) maxoutputlevel = 10
2100 outputmask => listgetintegerarray( currentmodel % Simulation, &
2101 'Output Level', gotit )
2104 DO i=1,
SIZE(outputmask)
2105 outputlevelmask(i-1) = outputmask(i) /= 0
2110 outputlevelmask(i) = outputlevelmask(i) .AND. &
2111 i >= minoutputlevel .AND. i <= maxoutputlevel
2114 outputprefix = listgetlogical( currentmodel % Simulation, &
2115 'Output Prefix', gotit )
2116 IF ( .NOT. gotit ) outputprefix = .false.
2118 outputcaller = listgetlogical( currentmodel % Simulation, &
2119 'Output Caller', gotit )
2120 IF ( .NOT. gotit ) outputcaller = .true.
subroutine setinitialconditions()
Sets initial conditions for the fields.
subroutine savecurrent(CurrentStep)
Saves current timestep to external files.
subroutine savetopost(CurrentStep)
Saves results file to post processing file of ElmerPost format, if requested.
type(model_t) function, pointer elmerloadmodel(ModelName, BoundariesOnly, numprocs, mype)
Release a mesh from the list of meshes.
subroutine restart()
Check if we are restarting are if yes, read in field values.
subroutine addvtuoutputsolverhack()
subroutine addsolvers()
Adds flags for active solvers.
subroutine addmeshcoordinatesandtime()
Adds coordinate and time variables to the current mesh structure.
subroutine execsimulation(TimeIntervals, CoupledMinIter, CoupledMaxIter, OutputIntervals, Transient, Scanning)
Execute the individual solvers in defined sequence.
subroutine initializeoutputlevel()
ElmerLib Elmer library routines
subroutine getdefs(ElementDef)