Skip to content

Commit

Permalink
1) turn fypp to F90; 2) add a Fortran unit test for MultiField
Browse files Browse the repository at this point in the history
  • Loading branch information
sbrdar committed Sep 7, 2023
1 parent 7ee251a commit 55f66a0
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/atlas/field/FieldSet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ Field FieldSetImpl::add(const Field& field) {
}

void FieldSetImpl::add_fieldset(const FieldSet& fieldset) {
for( auto& field : fieldset) {
add(field);
for( auto field : fieldset) {
this->add(field);
}
}

Expand Down
19 changes: 17 additions & 2 deletions src/atlas/field/detail/MultiFieldInterface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <sstream>

#include "atlas/library/config.h"
#include "atlas/field/MultiField.h"
#include "atlas/field/detail/MultiFieldInterface.h"
#include "atlas/runtime/Exception.h"

Expand All @@ -21,6 +22,16 @@ namespace field {
extern "C" {
MultiFieldImpl* atlas__MultiField__create(eckit::Configuration* config) {
ATLAS_ASSERT(config != nullptr);

// Register in factory
// TODO: move __multiFieldCreatorIFS out of test_multifield_ifs.cc
//MultiFieldCreatorBuilder<MultiFieldCreatorIFS> __MultiFieldCreatorIFS("MultiFieldCreatorIFS");

//MultiField* multifield = new MultiField(*config);
//return multifield->get();

// TODO
// repeat here the code for __multiFieldCreatorIFS out of test_multifield_ifs.cc
long nproma = config->getLong("nproma");
long nlev = config->getLong("nlev");
long nblk = 0;
Expand Down Expand Up @@ -123,8 +134,12 @@ void atlas__MultiField__delete(MultiFieldImpl* This) {
delete This;
}

FieldSet* atlas__MultiField__fieldset(MultiFieldImpl* This) {
return &This->fieldset();
int atlas__MultiField__size(MultiFieldImpl* This) {
return This->size();
}

FieldSetImpl* atlas__MultiField__fieldset(MultiFieldImpl* This) {
return This->fieldset().get();
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/atlas/field/detail/MultiFieldInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ namespace field {
extern "C" {
MultiFieldImpl* atlas__MultiField__create(eckit::Configuration* config);
void atlas__MultiField__delete(MultiFieldImpl* This);
FieldSet* atlas__MultiField__fieldset(MultiFieldImpl* This);
int atlas__MultiField__size(MultiFieldImpl* This);
FieldSetImpl* atlas__MultiField__fieldset(MultiFieldImpl* This);
}

//----------------------------------------------------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/atlas_f/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ ecbuild_add_library( TARGET atlas_f
field/atlas_FieldSet_module.fypp
field/atlas_State_module.F90
field/atlas_Field_module.fypp
field/atlas_MultiField_module.fypp
field/atlas_MultiField_module.F90
grid/atlas_Grid_module.F90
grid/atlas_GridDistribution_module.F90
grid/atlas_Vertical_module.F90
Expand Down
125 changes: 125 additions & 0 deletions src/atlas_f/field/atlas_MultiField_module.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
! (C) Copyright 2013 ECMWF.
!
! This software is licensed under the terms of the Apache Licence Version 2.0
! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
! In applying this licence, ECMWF does not waive the privileges and immunities
! granted to it by virtue of its status as an intergovernmental organisation nor
! does it submit to any jurisdiction.

#include "atlas/atlas_f.h"

module atlas_multifield_module

use fckit_owned_object_module, only : fckit_owned_object
use atlas_Config_module, only: atlas_Config
use atlas_fieldset_module, only: atlas_fieldset

implicit none

public :: atlas_MultiField

private

!------------------------------------------------------------------------------
TYPE, extends(fckit_owned_object) :: atlas_MultiField

! Purpose :
! -------
! *MultiField* : Object containing field data and Metadata

! Methods :
! -------
! name : The name or tag this field was created with
! data : Return the field as a fortran array of specified shape
! Metadata : Return object that can contain a variety of Metadata

! Author :
! ------
! 20-Nov-2013 Willem Deconinck *ECMWF*
! 29-Aug-2023 Slavko Brdar *ECMWF*

!------------------------------------------------------------------------------
contains
procedure, public :: MultiField__fieldset
procedure, public :: MultiField__size
generic :: fieldset => MultiField__fieldset
generic :: size => MultiField__size

#if FCKIT_FINAL_NOT_INHERITING
final :: atlas_MultiField__final_auto
#endif

END TYPE

interface atlas_MultiField
module procedure atlas_MultiField__cptr
module procedure atlas_MultiField__create
end interface

private :: fckit_owned_object
private :: atlas_Config

!========================================================
contains
!========================================================

!-------------------------------------------------------------------------------

function atlas_MultiField__cptr(cptr) result(field)
use, intrinsic :: iso_c_binding, only : c_ptr
type(atlas_MultiField) :: field
type(c_ptr), intent(in) :: cptr
call field%reset_c_ptr( cptr )
call field%return()
end function

!-------------------------------------------------------------------------------

function atlas_MultiField__create(params) result(field)
use atlas_multifield_c_binding
type(atlas_MultiField) :: field
class(atlas_Config), intent(in) :: params
field = atlas_MultiField__cptr( atlas__MultiField__create(params%CPTR_PGIBUG_B) )
call field%return()
end function

!-------------------------------------------------------------------------------

function MultiField__size(this) result(size)
use atlas_multifield_c_binding
class(atlas_MultiField), intent(in) :: this
integer :: size
size = atlas__MultiField__size(this%CPTR_PGIBUG_B)
end function

!-------------------------------------------------------------------------------
function MultiField__fieldset(this) result(fset)
use, intrinsic :: iso_c_binding, only : c_ptr
use atlas_multifield_c_binding
class(atlas_MultiField), intent(in) :: this
type(c_ptr) :: fset_cptr
type(atlas_FieldSet) :: fset
fset_cptr = atlas__MultiField__fieldset(this%CPTR_PGIBUG_B)
fset = atlas_FieldSet( fset_cptr )
call fset%return()
end function

!-------------------------------------------------------------------------------

#if FCKIT_FINAL_NOT_INHERITING
ATLAS_FINAL subroutine atlas_MultiField__final_auto(this)
type(atlas_MultiField), intent(inout) :: this
#if FCKIT_FINAL_DEBUGGING
write(0,*) "atlas_MultiField__final_auto"
#endif
#if FCKIT_FINAL_NOT_PROPAGATING
call this%final()
#endif
FCKIT_SUPPRESS_UNUSED( this )
end subroutine
#endif

!-------------------------------------------------------------------------------

end module atlas_multifield_module

15 changes: 13 additions & 2 deletions src/tests/field/fctest_multifield_ifs.F90
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module fcta_MultiField_fixture

! -----------------------------------------------------------------------------

TESTSUITE_WITH_FIXTURE(fctest_atlas_MultiField,fcta_MultiField_fixture)
TESTSUITE_WITH_FIXTURE(fctest_atlas_MultiField, fcta_MultiField_fixture)

! -----------------------------------------------------------------------------

Expand All @@ -46,6 +46,7 @@ module fcta_MultiField_fixture
type(atlas_FieldSet) :: fieldset_1, fieldset_2
type(atlas_Field) :: field
type(atlas_config) :: config
real(c_double), pointer :: view(:,:,:)

integer, parameter :: nvar = 5;
integer, parameter :: nproma = 16;
Expand All @@ -72,10 +73,20 @@ module fcta_MultiField_fixture
call config%set("fields", field_configs)

multifield = atlas_MultiField(config)
FCTEST_CHECK_EQUAL(multifield%size(), 5)

fieldset_1 = multifield%fieldset()
call fieldset_2%add(fieldset_1)
FCTEST_CHECK_EQUAL(fieldset_1%size(), 5)

fieldset_2 = atlas_FieldSet()
call fieldset_2%add(multifield%fieldset())
field = fieldset_2%field("density")
call field%data(view)
view(1,1,1) = 2

field = fieldset_1%field("density")
call field%data(view)
FCTEST_CHECK_EQUAL(view(1,1,1), 2)
END_TEST

! -----------------------------------------------------------------------------
Expand Down
8 changes: 8 additions & 0 deletions src/tests/field/test_multifield_ifs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,14 @@ CASE("multifield_create") {

EXPECT_EQ(multiarray.size(), nblk * nvar * nlev * nproma);
}

// access FieldSet through MultiField
auto fieldset = multifield->fieldset();
auto field_v = array::make_view<Value,3>(fieldset.field("temperature"));
EXPECT_EQ(fieldset.size(), 5);
EXPECT(fieldset.has("temperature"));
EXPECT(fieldset.has("wind_u"));
EXPECT_EQ(field_v(1,2,3), 4);
}

SECTION("test registry") {
Expand Down

0 comments on commit 55f66a0

Please sign in to comment.