File: NodeColumns.cc

package info (click to toggle)
metview 5.26.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 614,356 kB
  • sloc: cpp: 560,586; ansic: 44,641; xml: 19,933; f90: 17,984; sh: 7,454; python: 5,565; yacc: 2,318; lex: 1,372; perl: 701; makefile: 88
file content (154 lines) | stat: -rw-r--r-- 5,846 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include "atlas/functionspace/NodeColumns.h"
#include "atlas/array/ArrayView.h"
#include "atlas/field.h"
#include "atlas/grid.h"
#include "atlas/library.h"
#include "atlas/mesh.h"
#include "atlas/meshgenerator.h"
#include "atlas/output/Gmsh.h"
#include "atlas/runtime/Log.h"

using namespace atlas;
using atlas::gidx_t;
using atlas::idx_t;
using atlas::StructuredGrid;
using atlas::StructuredMeshGenerator;
using atlas::array::make_shape;
using atlas::array::make_view;
using atlas::functionspace::NodeColumns;
using atlas::output::Gmsh;

int main( int argc, char* argv[] ) {
    atlas::initialise( argc, argv );

    // Generate global classic reduced Gaussian grid
    StructuredGrid grid( "N32" );

    // Generate mesh associated to structured grid
    StructuredMeshGenerator meshgenerator;
    Mesh mesh = meshgenerator.generate( grid );

    // Number of nodes in the mesh
    // (different from number of points on a grid!)
    size_t nb_nodes = mesh.nodes().size();

    // Number of vertical levels required
    size_t nb_levels = 10;

    // Generate functionspace associated to mesh
    NodeColumns fs_nodes( mesh, option::levels( nb_levels ) | option::halo( 1 ) );

    // Note on field generation
    Field field_scalar1 = fs_nodes.createField<double>( option::name( "scalar1" ) | option::levels( false ) );
    Field field_scalar2 = fs_nodes.createField<double>( option::name( "scalar2" ) );
    Field field_vector1 =
        fs_nodes.createField<double>( option::name( "vector1" ) | option::levels( false ) | option::variables( 2 ) );
    Field field_vector2 = fs_nodes.createField<double>( option::name( "vector2" ) | option::variables( 2 ) );
    Field field_tensor1 = fs_nodes.createField<double>( option::name( "tensor1" ) | option::levels( false ) |
                                                        option::variables( 2 * 2 ) );
    Field field_tensor2 = fs_nodes.createField<double>( option::name( "tensor2" ) | option::variables( 2 * 2 ) );
    /* .... */
    // Variables for scalar1 field definition
    const double rpi     = 2.0 * asin( 1.0 );
    const double deg2rad = rpi / 180.;
    const double zlatc   = 0.0 * rpi;
    const double zlonc   = 1.0 * rpi;
    const double zrad    = 2.0 * rpi / 9.0;
    double zdist, zlon, zlat;

    // Retrieve lonlat field to calculate scalar1 function
    auto scalar1 = make_view<double, 1>( field_scalar1 );
    auto lonlat  = make_view<double, 2>( mesh.nodes().lonlat() );
    for ( size_t jnode = 0; jnode < nb_nodes; ++jnode ) {
        zlon = lonlat( jnode, size_t( 0 ) ) * deg2rad;
        zlat = lonlat( jnode, size_t( 1 ) ) * deg2rad;

        zdist =
            2.0 * sqrt( ( cos( zlat ) * sin( ( zlon - zlonc ) / 2 ) ) * ( cos( zlat ) * sin( ( zlon - zlonc ) / 2 ) ) +
                        sin( ( zlat - zlatc ) / 2 ) * sin( ( zlat - zlatc ) / 2 ) );

        scalar1( jnode ) = 0.0;
        if ( zdist < zrad ) {
            scalar1( jnode ) = 0.5 * ( 1. + cos( rpi * zdist / zrad ) );
        }
    }

    // Write mesh and field in gmsh format for visualization
    Gmsh gmsh( "scalar1.msh" );
    gmsh.write( mesh );
    gmsh.write( field_scalar1 );

    /* .... */
    // Halo exchange
    fs_nodes.haloExchange( field_scalar1 );
    std::string checksum = fs_nodes.checksum( field_scalar1 );
    Log::info() << checksum << std::endl;

    // Create a global field
    Field field_global = fs_nodes.createField( field_scalar1, option::name( "global" ) | option::global() );
    // Gather operation
    fs_nodes.gather( field_scalar1, field_global );

    Log::info() << "local nodes         = " << fs_nodes.nb_nodes() << std::endl;
    Log::info() << "grid points          = " << grid.size() << std::endl;
    Log::info() << "field_global.shape(0) = " << field_global.shape( 0 ) << std::endl;

    // Scatter operation
    fs_nodes.scatter( field_global, field_scalar1 );

    // Halo exchange and checksum
    fs_nodes.haloExchange( field_scalar1 );
    checksum = fs_nodes.checksum( field_scalar1 );
    Log::info() << field_scalar1.name() << " checksum : " << checksum << std::endl;

    // FieldSet checksum
    FieldSet fields;
    fields.add( field_scalar1 );
    fields.add( field_vector1 );
    checksum = fs_nodes.checksum( fields );
    Log::info() << "FieldSet checksum : " << checksum << std::endl;

    /* .... */

    // Operations
    idx_t N;
    gidx_t gidx_min, gidx_max;
    double min, max, sum, mean, stddev;

    // Minimum and maximum
    fs_nodes.minimum( field_scalar1, min );
    fs_nodes.maximum( field_scalar1, max );
    Log::info() << "min: " << min << std::endl;
    Log::info() << "max: " << max << std::endl;

    // Minimum and maximum + location
    fs_nodes.minimumAndLocation( field_scalar1, min, gidx_min );
    fs_nodes.maximumAndLocation( field_scalar1, max, gidx_max );
    Log::info() << "min: " << min << ",  "
                << "global_id = " << gidx_min << std::endl;
    Log::info() << "max: " << max << ",  "
                << "global_id = " << gidx_max << std::endl;

    // Summation
    fs_nodes.sum( field_scalar1, sum, N );
    Log::info() << "sum: " << sum << ", nb_nodes = " << N << std::endl;

    // Order independent (from partitioning) summation
    fs_nodes.orderIndependentSum( field_scalar1, sum, N );
    Log::info() << "oi_sum: " << sum << ", nb_nodes = " << N << std::endl;

    // Average over number of nodes
    fs_nodes.mean( field_scalar1, mean, N );
    Log::info() << "mean: " << mean << ", nb_nodes = " << N << std::endl;

    // Average and standard deviation over number of nodes
    fs_nodes.meanAndStandardDeviation( field_scalar1, mean, stddev, N );
    Log::info() << "mean = " << mean << ",  "
                << "std_deviation: " << stddev << ",  "
                << "nb_nodes: " << N << std::endl;

    atlas::finalise();
    atlas::mpi::finalize();

    return 0;
}