Skip to content

Conversation

@suvarchal
Copy link
Collaborator

@suvarchal suvarchal commented Jul 5, 2025

This PR cleans up needless module interfaces for subroutines/procedures outside of module scope. we have files named as modules (or wanna be modules) but have multiple modules as interfaces for dangling subroutines. For instance, see

fesom2/src/oce_dyn.F90

Lines 12 to 200 in 2d82154

module visc_filt_bcksct_interface
interface
subroutine visc_filt_bcksct(dynamics, partit, mesh)
use mod_mesh
USE MOD_PARTIT
USE MOD_PARSUP
USE MOD_DYN
type(t_dyn) , intent(inout), target :: dynamics
type(t_partit), intent(inout), target :: partit
type(t_mesh) , intent(in) , target :: mesh
end subroutine visc_filt_bcksct
end interface
end module visc_filt_bcksct_interface
module visc_filt_bilapl_interface
interface
subroutine visc_filt_bilapl(dynamics, partit, mesh)
use mod_mesh
USE MOD_PARTIT
USE MOD_PARSUP
USE MOD_DYN
type(t_dyn) , intent(inout), target :: dynamics
type(t_partit), intent(inout), target :: partit
type(t_mesh) , intent(in) , target :: mesh
end subroutine visc_filt_bilapl
end interface
end module visc_filt_bilapl_interface
module visc_filt_bidiff_interface
interface
subroutine visc_filt_bidiff(dynamics, partit, mesh)
use mod_mesh
USE MOD_PARTIT
USE MOD_PARSUP
USE MOD_DYN
type(t_dyn) , intent(inout), target :: dynamics
type(t_partit), intent(inout), target :: partit
type(t_mesh) , intent(in) , target :: mesh
end subroutine visc_filt_bidiff
end interface
end module visc_filt_bidiff_interface
module check_validviscopt_interface
interface
subroutine check_validviscopt_5(partit, mesh)
USE MOD_MESH
USE MOD_PARTIT
USE MOD_PARSUP
type(t_partit), intent(inout), target :: partit
type(t_mesh) , intent(in) , target :: mesh
end subroutine check_validviscopt_5
end interface
end module check_validviscopt_interface
!
! Contains routines needed for computations of dynamics.
! includes: update_vel, compute_vel_nodes
!_______________________________________________________________________________
SUBROUTINE update_vel(dynamics, partit, mesh)
USE MOD_MESH
USE MOD_PARTIT
USE MOD_PARSUP
USE MOD_DYN
USE o_PARAM
USE g_CONFIG
use g_comm_auto
IMPLICIT NONE
type(t_dyn) , intent(inout), target :: dynamics
type(t_partit), intent(inout), target :: partit
type(t_mesh) , intent(in) , target :: mesh
!___________________________________________________________________________
integer :: n, elem, elnodes(3), nz, nzmin, nzmax
real(kind=WP) :: eta(3)
real(kind=WP) :: Fx, Fy
real(kind=WP) :: usum(2), udiff(2)
!___________________________________________________________________________
! pointer on necessary derived types
real(kind=WP), dimension(:,:,:), pointer :: UV, UV_rhs
real(kind=WP), dimension(:) , pointer :: eta_n, d_eta
#include "associate_part_def.h"
#include "associate_mesh_def.h"
#include "associate_part_ass.h"
#include "associate_mesh_ass.h"
UV => dynamics%uv(:,:,:)
UV_rhs => dynamics%uv_rhs(:,:,:)
eta_n => dynamics%eta_n(:)
d_eta => dynamics%d_eta(:)
!___________________________________________________________________________
!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(elem, elnodes, nz, nzmin, nzmax, eta, Fx, Fy, usum, udiff)
DO elem=1, myDim_elem2D
elnodes=elem2D_nodes(:,elem)
eta=-g*theta*dt*d_eta(elnodes)
Fx=sum(gradient_sca(1:3,elem)*eta)
Fy=sum(gradient_sca(4:6,elem)*eta)
nzmin = ulevels(elem)
nzmax = nlevels(elem)
if (dynamics%ldiag_ke) then
DO nz=nzmin, nzmax-1
dynamics%ke_pre(1,nz,elem) =dynamics%ke_pre(1,nz,elem) + Fx
dynamics%ke_pre(2,nz,elem) =dynamics%ke_pre(2,nz,elem) + Fy
! U_(n+1) - U_n = Urhs_n |* (U_(n+1)+U_n)
! U_(n+1)^2 - U_n^2 = Urhs_n * (U_(n+1)+U_n)
! |
! +-> U_(n+1) = U_n+Urhs_n
! U_(n+1)^2 - U_n^2 = Urhs_n * (2*U_n + Urhs)
! | |
! v v
! udiff usum
usum(1) = 2.0_WP*UV(1,nz,elem)+(UV_rhs(1,nz,elem) + Fx)
usum(2) = 2.0_WP*UV(2,nz,elem)+(UV_rhs(2,nz,elem) + Fy)
udiff(1) = UV_rhs(1,nz,elem) + Fx
udiff(2) = UV_rhs(2,nz,elem) + Fy
! (U_(n+1)^2 - U_n^2)/2 = usum*udiff/2
dynamics%ke_du2 (:,nz,elem) = usum*udiff/2.0_WP
dynamics%ke_pre_xVEL (:,nz,elem) = usum*dynamics%ke_pre (:,nz,elem)/2.0_WP
dynamics%ke_adv_xVEL (:,nz,elem) = usum*dynamics%ke_adv (:,nz,elem)/2.0_WP
dynamics%ke_cor_xVEL (:,nz,elem) = usum*dynamics%ke_cor (:,nz,elem)/2.0_WP
dynamics%ke_hvis_xVEL(:,nz,elem) = usum*dynamics%ke_hvis(:,nz,elem)/2.0_WP
dynamics%ke_vvis_xVEL(:,nz,elem) = usum*dynamics%ke_vvis(:,nz,elem)/2.0_WP
! U_(n+0.5) = U_n + 0.5*Urhs
dynamics%ke_umean( :,nz,elem) = usum/2.0_WP
! U_(n+0.5)^2
dynamics%ke_u2mean( :,nz,elem) = (usum*usum)/4.0_WP
if (nz==nzmin) then
dynamics%ke_wind_xVEL(:,elem) = usum*dynamics%ke_wind(:,elem)/2.0_WP
end if
if (nz==nzmax-1) then
dynamics%ke_drag_xVEL(:,elem) = usum*dynamics%ke_drag(:,elem)/2.0_WP
end if
END DO
end if
DO nz=nzmin, nzmax-1
UV(1,nz,elem)= UV(1,nz,elem) + UV_rhs(1,nz,elem) + Fx
UV(2,nz,elem)= UV(2,nz,elem) + UV_rhs(2,nz,elem) + Fy
END DO
END DO
!$OMP END PARALLEL DO
!$OMP BARRIER
!!PS Why we do this here eta_n is anyway overwriten through ...
!!PS do node=1, myDim_nod2D+eDim_nod2D
!!PS if (ulevels_nod2D(node)==1) eta_n(node)=alpha*hbar(node)+(1.0_WP-alpha)*hbar_old(node)
!!PS end do
!!PS !$OMP PARALLEL DO
!!PS DO n=1, myDim_nod2D+eDim_nod2D
!!PS eta_n(n)=eta_n(n)+d_eta(n)
!!PS END DO
!!PS !$OMP END PARALLEL DO
call exchange_elem(UV, partit)
end subroutine update_vel
!
!
!_______________________________________________________________________________
subroutine compute_vel_nodes(dynamics, partit, mesh)
USE MOD_MESH
USE MOD_PARTIT
USE MOD_PARSUP
USE MOD_DYN
USE o_PARAM
use g_comm_auto
IMPLICIT NONE
type(t_dyn) , intent(inout), target :: dynamics
type(t_partit), intent(inout), target :: partit
type(t_mesh) , intent(in) , target :: mesh
!___________________________________________________________________________
integer :: n, nz, k, elem, nln, uln, nle, ule
real(kind=WP) :: tx, ty, tvol
!___________________________________________________________________________
! pointer on necessary derived types
real(kind=WP), dimension(:,:,:), pointer :: UV, UVnode
#include "associate_part_def.h"
#include "associate_mesh_def.h"
#include "associate_part_ass.h"
#include "associate_mesh_ass.h"
UV=>dynamics%uv(:,:,:)
UVnode=>dynamics%uvnode(:,:,:)
!___________________________________________________________________________
, each of these interfaces just wrap one subroutine and define types again inside. This is hard to maintain because if subroutine has to be changed for type say to single precision for a array then we also need to modify the interface too. Moreover when these subroutines need to be used else where we have to use use module_interface_sub1, sub2,sub3 ... we could instead just use from module_interface use sub1,sub2, sub3. this is cleaner, maintainable pattern for changing internal code and useful to have external interfaces such as calling these routines from python or other model. for some parts this is a simpler fix by wrapping the current module with a module and end module and remove needless interfaces and use the procedures from this module. For instance see change for above oce_dyn.F90 here

fesom2/src/oce_dyn.F90

Lines 1 to 200 in 70ee9ba

module oce_dyn_module
use mod_mesh
USE MOD_PARTIT
USE MOD_PARSUP
USE MOD_DYN
USE o_PARAM
USE g_CONFIG
use g_comm_auto
implicit none
private
public :: update_vel, compute_vel_nodes, viscosity_filter, visc_filt_bcksct, &
visc_filt_bilapl, visc_filt_bidiff, compute_ke_wrho, compute_apegen, &
check_viscopt, check_validviscopt_5
contains
! A set of routines for computing the horizonlal viscosity
! the control parameters (their default values) are:
! dynamics%visc_gamma0 (0.01 [m/s]), dynamics%visc_gamma1 (0.1 [no dim.]), dynamics%visc_gamma2 (10.[s/m]), Div_c [1.], Leith_c[1.?]
! 1. dynamics%visc_gamma0 has the dimension of velocity. It should be as small as possible, but in any case smaller than 0.01 m/s.
! All major ocean circulation models are stable with harmonic viscosity 0.01*len.
! 2. dynamics%visc_gamma1 is nondimensional. In commonly used Leith or Smagorinsky parameterizations it is C/pi^2=0.1 (C is about 1).
! We therefore try to follow this, allowing some adjustments (because our mesh is triangular, our resolution is different, etc.).
! We however, try to keep dynamics%visc_gamma1<0.1
! 3. dynamics%visc_gamma2 is dimensional (1/velocity). If it is 10, then the respective term dominates starting from |u|=0.1 m/s an so on. It is only used in:
! (5) visc_filt_bcksct, (6) visc_filt_bilapl, (7) visc_filt_bidiff
!
! Contains routines needed for computations of dynamics.
! includes: update_vel, compute_vel_nodes
!_______________________________________________________________________________
SUBROUTINE update_vel(dynamics, partit, mesh)
type(t_dyn) , intent(inout), target :: dynamics
type(t_partit), intent(inout), target :: partit
type(t_mesh) , intent(in) , target :: mesh
!___________________________________________________________________________
integer :: n, elem, elnodes(3), nz, nzmin, nzmax
real(kind=WP) :: eta(3)
real(kind=WP) :: Fx, Fy
real(kind=WP) :: usum(2), udiff(2)
!___________________________________________________________________________
! pointer on necessary derived types
real(kind=WP), dimension(:,:,:), pointer :: UV, UV_rhs
real(kind=WP), dimension(:) , pointer :: eta_n, d_eta
#include "associate_part_def.h"
#include "associate_mesh_def.h"
#include "associate_part_ass.h"
#include "associate_mesh_ass.h"
UV => dynamics%uv(:,:,:)
UV_rhs => dynamics%uv_rhs(:,:,:)
eta_n => dynamics%eta_n(:)
d_eta => dynamics%d_eta(:)
!___________________________________________________________________________
!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(elem, elnodes, nz, nzmin, nzmax, eta, Fx, Fy, usum, udiff)
DO elem=1, myDim_elem2D
elnodes=elem2D_nodes(:,elem)
eta=-g*theta*dt*d_eta(elnodes)
Fx=sum(gradient_sca(1:3,elem)*eta)
Fy=sum(gradient_sca(4:6,elem)*eta)
nzmin = ulevels(elem)
nzmax = nlevels(elem)
if (dynamics%ldiag_ke) then
DO nz=nzmin, nzmax-1
dynamics%ke_pre(1,nz,elem) =dynamics%ke_pre(1,nz,elem) + Fx
dynamics%ke_pre(2,nz,elem) =dynamics%ke_pre(2,nz,elem) + Fy
! U_(n+1) - U_n = Urhs_n |* (U_(n+1)+U_n)
! U_(n+1)^2 - U_n^2 = Urhs_n * (U_(n+1)+U_n)
! |
! +-> U_(n+1) = U_n+Urhs_n
! U_(n+1)^2 - U_n^2 = Urhs_n * (2*U_n + Urhs)
! | |
! v v
! udiff usum
usum(1) = 2.0_WP*UV(1,nz,elem)+(UV_rhs(1,nz,elem) + Fx)
usum(2) = 2.0_WP*UV(2,nz,elem)+(UV_rhs(2,nz,elem) + Fy)
udiff(1) = UV_rhs(1,nz,elem) + Fx
udiff(2) = UV_rhs(2,nz,elem) + Fy
! (U_(n+1)^2 - U_n^2)/2 = usum*udiff/2
dynamics%ke_du2 (:,nz,elem) = usum*udiff/2.0_WP
dynamics%ke_pre_xVEL (:,nz,elem) = usum*dynamics%ke_pre (:,nz,elem)/2.0_WP
dynamics%ke_adv_xVEL (:,nz,elem) = usum*dynamics%ke_adv (:,nz,elem)/2.0_WP
dynamics%ke_cor_xVEL (:,nz,elem) = usum*dynamics%ke_cor (:,nz,elem)/2.0_WP
dynamics%ke_hvis_xVEL(:,nz,elem) = usum*dynamics%ke_hvis(:,nz,elem)/2.0_WP
dynamics%ke_vvis_xVEL(:,nz,elem) = usum*dynamics%ke_vvis(:,nz,elem)/2.0_WP
! U_(n+0.5) = U_n + 0.5*Urhs
dynamics%ke_umean( :,nz,elem) = usum/2.0_WP
! U_(n+0.5)^2
dynamics%ke_u2mean( :,nz,elem) = (usum*usum)/4.0_WP
if (nz==nzmin) then
dynamics%ke_wind_xVEL(:,elem) = usum*dynamics%ke_wind(:,elem)/2.0_WP
end if
if (nz==nzmax-1) then
dynamics%ke_drag_xVEL(:,elem) = usum*dynamics%ke_drag(:,elem)/2.0_WP
end if
END DO
end if
DO nz=nzmin, nzmax-1
UV(1,nz,elem)= UV(1,nz,elem) + UV_rhs(1,nz,elem) + Fx
UV(2,nz,elem)= UV(2,nz,elem) + UV_rhs(2,nz,elem) + Fy
END DO
END DO
!$OMP END PARALLEL DO
!$OMP BARRIER
!!PS Why we do this here eta_n is anyway overwriten through ...
!!PS do node=1, myDim_nod2D+eDim_nod2D
!!PS if (ulevels_nod2D(node)==1) eta_n(node)=alpha*hbar(node)+(1.0_WP-alpha)*hbar_old(node)
!!PS end do
!!PS !$OMP PARALLEL DO
!!PS DO n=1, myDim_nod2D+eDim_nod2D
!!PS eta_n(n)=eta_n(n)+d_eta(n)
!!PS END DO
!!PS !$OMP END PARALLEL DO
call exchange_elem(UV, partit)
end subroutine update_vel
!
!
!_______________________________________________________________________________
subroutine compute_vel_nodes(dynamics, partit, mesh)
type(t_dyn) , intent(inout), target :: dynamics
type(t_partit), intent(inout), target :: partit
type(t_mesh) , intent(in) , target :: mesh
!___________________________________________________________________________
integer :: n, nz, k, elem, nln, uln, nle, ule
real(kind=WP) :: tx, ty, tvol
!___________________________________________________________________________
! pointer on necessary derived types
real(kind=WP), dimension(:,:,:), pointer :: UV, UVnode
#include "associate_part_def.h"
#include "associate_mesh_def.h"
#include "associate_part_ass.h"
#include "associate_mesh_ass.h"
UV=>dynamics%uv(:,:,:)
UVnode=>dynamics%uvnode(:,:,:)
!___________________________________________________________________________
!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(n, nz, k, elem, nln, uln, nle, ule, tx, ty, tvol)
DO n=1, myDim_nod2D
uln = ulevels_nod2D(n)
nln = nlevels_nod2D(n)
DO nz=uln, nln-1
tvol=0.0_WP
tx =0.0_WP
ty =0.0_WP
DO k=1, nod_in_elem2D_num(n)
elem=nod_in_elem2D(k,n)
ule = ulevels(elem)
nle = nlevels(elem)
!!PS if (nlevels(elem)-1<nz) cycle
if (nle-1<nz .or. nz<ule) cycle
tvol=tvol+elem_area(elem)
tx=tx+UV(1,nz,elem)*elem_area(elem)
ty=ty+UV(2,nz,elem)*elem_area(elem)
END DO
UVnode(1,nz,n)=tx/tvol
UVnode(2,nz,n)=ty/tvol
END DO
END DO
!$OMP END PARALLEL DO
!$OMP BARRIER
call exchange_nod(UVnode, partit)
end subroutine compute_vel_nodes
!
!
!_______________________________________________________________________________
subroutine viscosity_filter(option, dynamics, partit, mesh)
use o_PARAM
use MOD_MESH
USE MOD_PARTIT
USE MOD_PARSUP
use MOD_DYN
! visc_filt subroutines are now in the same module
use g_backscatter
IMPLICIT NONE
integer :: option
type(t_dyn) , intent(inout), target :: dynamics
type(t_partit), intent(inout), target :: partit
type(t_mesh) , intent(in) , target :: mesh
! Driving routine
! Background viscosity is selected in terms of Vl, where V is
! background velocity scale and l is the resolution. V is 0.005
! or 0.01, perhaps it would be better to pass it as a parameter.
! h_viscosity_leiht needs vorticity, so vorticity array should be
! allocated. At present, there are two rounds of smoothing in
! h_viscosity.
SELECT CASE (option)
CASE (5)
if (flag_debug .and. partit%mype==0) print *, achar(27)//'[37m'//' --> call visc_filt_bcksct'//achar(27)//'[0m'
and how it is used here

fesom2/src/oce_ale.F90

Lines 1 to 20 in 70ee9ba

module oce_ale_module
USE o_PARAM
USE MOD_MESH
USE MOD_PARTIT
USE MOD_PARSUP
USE MOD_DYN
USE o_ARRAYS
USE g_config
USE g_forcing_param, only: use_virt_salt
use solver_module, only: ssh_solve_preconditioner, ssh_solve_cg
use oce_dyn_module, only: viscosity_filter, update_vel, compute_apegen, check_viscopt, compute_ke_wrho
use oce_ale_pressure_bv_module, only: pressure_bv, pressure_force_4_linfs, pressure_force_4_zxxxx, &
sw_alpha_beta, compute_neutral_slope, compute_sigma_xy
implicit none
private
public :: init_ale, init_bottom_elem_thickness, init_bottom_node_thickness, &
init_surface_elem_depth, init_surface_node_depth, init_thickness_ale, &
update_thickness_ale, impl_vert_visc_ale, update_stiff_mat_ale, &

I guess this happened from early on migration from f77 and early f90 compilers would generate any implicit interface for dangling subroutines (that are outside module, program blocks) but as that practice slowly started getting discouraged because it is source of bugs compilers started to complain of need to have explicit interface for each dangling subroutine and we in time-rush wrote one for each subroutine when and where that compilation error came.

the benefits are cleaner code on multiple fronts like allows explicitly mentioning what procedures we are going to use, less boiler plate imports like use mod_mesh, mod_partit that are needed almost in every subroutine now gets just done at the top of module and shared. And for all above reasons it also allows agentic coding/RAG is much easier to figure out what procedure and their data dependency this way.

this PR reduces total compiled modules of fesom from 177 to 127, there are still a few contrived hard parts, it is a bit slow process as most of these changes are better done manually and need some care, but once done i believe our code can use super agentic powers :).

@suvarchal suvarchal marked this pull request as draft July 5, 2025 22:19
suvarchal and others added 17 commits July 6, 2025 00:29
…roper results and intents, remove legacy module-interfaces, and update references
… needless module-interfaces, and update references
This reverts commit 1ab73c5.

for some reason tests fail will address this later
This reverts commit f7da71a.

remove testing for blowup functionality, add later
…e and update references"

This reverts commit db1ab78.

undo modularization of gen_modules_partitioning.F90 to be done laterwq
…, remove needless module-interfaces, and update references"

This reverts commit ad56252.
@suvarchal suvarchal marked this pull request as ready for review September 8, 2025 15:19
@JanStreffing
Copy link
Collaborator

[ 76%] Building Fortran object src/CMakeFiles/fesom.dir/oce_adv_tra_fct.F90.o
[ 76%] Building Fortran object src/CMakeFiles/fesom.dir/oce_shortwave_pene_dbgyre.F90.o
associate_mesh_ass.h:67:2:

Warning: Illegal preprocessor directive
associate_mesh_ass.h:69:2:

Warning: Illegal preprocessor directive
associate_mesh_ass.h:67:2:

Warning: Illegal preprocessor directive
associate_mesh_ass.h:69:2:

Warning: Illegal preprocessor directive
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:75:14:

   75 |   REAL(kind=WP), POINTER                          :: exfld(:)          ! buffer for receiving global exchange fields
      |              1
Error: Symbol 'wp' at (1) has no IMPLICIT type
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:76:14:

   76 |   real(kind=WP), allocatable, dimension(:,:)      :: cplsnd
      |              1
Error: Symbol 'wp' at (1) has no IMPLICIT type
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:83:14:

   83 |   real(kind=WP), dimension(:,:),   allocatable   :: a2o_fcorr_stat  !flux correction statistics for the output
      |              1
Error: Symbol 'wp' at (1) has no IMPLICIT type
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:794:12:

  794 |    allocate(cplsnd(nsend, myDim_nod2D+eDim_nod2D))
      |            1
Error: Allocate-object at (1) is neither a data pointer nor an allocatable variable
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:795:12:

  795 |    allocate(exfld(myDim_nod2D))
      |            1
Error: Allocate-object at (1) is neither a data pointer nor an allocatable variable
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:849:26:

  849 |     exfld = cplsnd(ind, 1:partit%myDim_nod2D)/real(o2a_call_count)
      |                          1
Error: Syntax error in argument list at (1)
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:99:23:

   99 |   public a2o_fcorr_stat
      |                       1
Error: Symbol 'a2o_fcorr_stat' at (1) has no IMPLICIT type
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:912:55:

  912 |     call oasis_get(recv_id(ind), seconds_til_now, exfld,info)
      |                                                       1
Error: Symbol 'exfld' at (1) has no IMPLICIT type
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:896:36:

  896 |     integer, save          :: ncount = 0
      |                                    1
Warning: Legacy Extension: Duplicate SAVE attribute specified at (1)
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:861:16:

  861 |           cplsnd=0.
      |                1
Error: Symbol 'cplsnd' at (1) has no IMPLICIT type
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:857:55:

  857 |     call oasis_put(send_id(ind), seconds_til_now, exfld, info)
      |                                                       1
Error: Symbol 'exfld' at (1) has no IMPLICIT type
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:796:9:

  796 |    cplsnd=0.
      |         1
Error: Symbol 'cplsnd' at (1) has no IMPLICIT type; did you mean 'fplane'?
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:63:53:

   63 |   logical, save              :: oasis_was_initialized
      |                                                     1
Warning: Legacy Extension: Duplicate SAVE attribute specified at (1)
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:64:52:

   64 |   logical, save              :: oasis_was_terminated
      |                                                    1
Warning: Legacy Extension: Duplicate SAVE attribute specified at (1)
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:67:47:

   67 |   integer, save              :: seconds_til_now=0
      |                                               1
Warning: Legacy Extension: Duplicate SAVE attribute specified at (1)
/work/ab0246/a270092/model_codes/awicm3-develop/fesom-2.6/src/cpl_driver.F90:65:42:

   65 |   integer, save              :: write_grid
      |                                          1
Warning: Legacy Extension: Duplicate SAVE attribute specified at (1)
[ 76%] Building Fortran object src/CMakeFiles/fesom.dir/icb_dyn.F90.o
make[2]: *** [src/CMakeFiles/fesom.dir/build.make:205: src/CMakeFiles/fesom.dir/cpl_driver.F90.o] Error 1
make[2]: *** Waiting for unfinished jobs....

@suvarchal
Copy link
Collaborator Author

thanks to #774 coupled builds also work and averted a missing import in gen_coupled.F90.

Copy link
Collaborator Author

@suvarchal suvarchal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checked once again

@JanStreffing JanStreffing modified the milestones: FESOM 2.7, FESOM 2.8 Nov 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants