DNS.py 6.42 KB
Newer Older
Cristian Lalescu's avatar
Cristian Lalescu committed
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
#######################################################################
#                                                                     #
#  Copyright 2015 Max Planck Institute                                #
#                 for Dynamics and Self-Organization                  #
#                                                                     #
#  This file is part of bfps.                                         #
#                                                                     #
#  bfps is free software: you can redistribute it and/or modify       #
#  it under the terms of the GNU General Public License as published  #
#  by the Free Software Foundation, either version 3 of the License,  #
#  or (at your option) any later version.                             #
#                                                                     #
#  bfps is distributed in the hope that it will be useful,            #
#  but WITHOUT ANY WARRANTY; without even the implied warranty of     #
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      #
#  GNU General Public License for more details.                       #
#                                                                     #
#  You should have received a copy of the GNU General Public License  #
#  along with bfps.  If not, see <http://www.gnu.org/licenses/>       #
#                                                                     #
# Contact: Cristian.Lalescu@ds.mpg.de                                 #
#                                                                     #
#######################################################################



import os
import sys
import shutil
import subprocess
import argparse
import h5py
import math
import numpy as np
import warnings

import bfps
from ._code import _code

class DNS(_code):
    """This class is meant to stitch together the C++ code into a final source file,
    compile it, and handle all job launching.
    """
    def __init__(
            self,
            work_dir = './',
            simname = 'test',
            dns_type = 'NSVE',
            fluid_dtype = 'single'):
        _code.__init__(self, work_dir = work_dir, simname = simname)
        self.dns_type = dns_type
        self.name = self.dns_type + '-v' + bfps.__version__
        if fluid_dtype in [np.float32, np.float64]:
            self.fluid_dtype = fluid_dtype
        elif fluid_dtype in ['single', 'double']:
            if fluid_dtype == 'single':
                self.fluid_dtype = np.dtype(np.float32)
            elif fluid_dtype == 'double':
                self.fluid_dtype = np.dtype(np.float64)
        self.rtype = self.fluid_dtype
        if self.rtype == np.float32:
            self.ctype = np.dtype(np.complex64)
63
            self.C_field_dtype = 'float'
Cristian Lalescu's avatar
Cristian Lalescu committed
64
65
        elif self.rtype == np.float64:
            self.ctype = np.dtype(np.complex128)
66
            self.C_field_dtype = 'double'
Cristian Lalescu's avatar
Cristian Lalescu committed
67
68
69
70
71
        self.version_message = (
                '/***********************************************************************\n' +
                '* this code automatically generated by bfps\n' +
                '* version {0}\n'.format(bfps.__version__) +
                '***********************************************************************/\n\n\n')
72
73
74
75
76
77
78
79
80
81
82
83
84
85
        self.include_list = [
                '"base.hpp"',
                '"scope_timer.hpp"',
                '"fftw_interface.hpp"',
                '"full_code/main_code.hpp"',
                '<iostream>',
                '<hdf5.h>',
                '<string>',
                '<cstring>',
                '<fftw3-mpi.h>',
                '<omp.h>',
                '<cfenv>',
                '<cstdlib>',
                '"full_code/{0}.hpp"\n'.format(self.dns_type)]
Cristian Lalescu's avatar
Cristian Lalescu committed
86
87
88
89
90
91
        self.main = """
                int main(int argc, char *argv[])
                {{
                    bool fpe = (
                        (getenv("BFPS_FPE_OFF") == nullptr) ||
                        (getenv("BFPS_FPE_OFF") != std::string("TRUE")));
92
                    return main_code< {0} >(argc, argv, fpe);
Cristian Lalescu's avatar
Cristian Lalescu committed
93
                }}
94
                """.format(self.dns_type + '<{0}>'.format(self.C_field_dtype))
Cristian Lalescu's avatar
Cristian Lalescu committed
95
96
97
98
99
100
        self.host_info = {'type'        : 'cluster',
                          'environment' : None,
                          'deltanprocs' : 1,
                          'queue'       : '',
                          'mail_address': '',
                          'mail_events' : None}
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
        self.generate_default_parameters()
        return None
    def generate_default_parameters(self):
        # these parameters are relevant for all DNS classes
        self.parameters['dealias_type'] = 1
        self.parameters['dkx'] = 1.0
        self.parameters['dky'] = 1.0
        self.parameters['dkz'] = 1.0
        self.parameters['niter_todo'] = 8
        self.parameters['niter_stat'] = 1
        self.parameters['niter_out'] = 8
        self.parameters['checkpoints_per_file'] = int(1)
        self.parameters['dt'] = 0.01
        self.parameters['nu'] = float(0.1)
        self.parameters['fmode'] = 1
        self.parameters['famplitude'] = float(0.5)
        self.parameters['fk0'] = float(2.0)
        self.parameters['fk1'] = float(4.0)
        self.parameters['forcing_type'] = 'linear'
        self.parameters['histogram_bins'] = int(256)
        self.parameters['max_velocity_estimate'] = float(1)
        self.parameters['max_vorticity_estimate'] = float(1)
        # parameters specific to particle version
        if self.dns_type == 'NSVEp':
            self.parameters['niter_part'] = 1
            self.parameters['nparticles'] = 0
Cristian Lalescu's avatar
Cristian Lalescu committed
127
128
        return None
    def write_src(self):
129
130
131
        self.includes = '\n'.join(
                ['#include ' + hh
                 for hh in self.include_list])
Cristian Lalescu's avatar
Cristian Lalescu committed
132
        with open(self.name + '.cpp', 'w') as outfile:
133
134
            outfile.write(self.version_message + '\n\n')
            outfile.write(self.includes + '\n\n')
Cristian Lalescu's avatar
Cristian Lalescu committed
135
            outfile.write(self.cread_pars(
136
                template_class = '{0}<rnumber>::'.format(self.dns_type),
Cristian Lalescu's avatar
Cristian Lalescu committed
137
                template_prefix = 'template <typename rnumber> ',
138
                simname_variable = 'simname.c_str()') + '\n\n')
Cristian Lalescu's avatar
Cristian Lalescu committed
139
140
            for rnumber in ['float', 'double']:
                outfile.write(self.cread_pars(
141
                    template_class = '{0}<{1}>::'.format(self.dns_type, rnumber),
Cristian Lalescu's avatar
Cristian Lalescu committed
142
                    template_prefix = 'template '.format(rnumber),
143
144
                    just_declaration = True) + '\n\n')
            outfile.write(self.main + '\n')
Cristian Lalescu's avatar
Cristian Lalescu committed
145
146
        return None