~reducedmodelling/fluidity/ReducedModel

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
// wrapper for petsc_readnsolve main
#include "confdefs.h"

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <cstdlib>
#include <iostream>
#include <string.h>
#include <sstream>

#ifdef HAVE_MPI
#include <mpi.h>
#endif

#ifdef HAVE_PETSC
#include <petsc.h>
#endif

using std::cerr;
using std::endl;
using std::string;
using std::ostringstream;


extern "C"{
void petsc_readnsolve_();
#ifdef HAVE_PYTHON
#include "python_statec.h"
#endif
}

void usage(int argc, char **argv){
// Users are allowed to specify the flml and field name as 2 consecutive
// *non-optional* arguments. As PETSc doesn't really provide a way to
// access those, and we can't access the command-line from fortran
// We read those here and stick them in the PETSc options database to be
// read from fortran
  
  char flml_extension[]=".flml";
  char *flml_file=NULL;
  PetscErrorCode ierr;
  PetscTruth     flg;
  
  // if it's already specified as a PETSc option, we do nothing:
  ierr = PetscOptionsHasName("prns_","-flml",&flg);
  if (flg) {
    return;
  }
  // search for any argument ending in .flml
  int i;
  for (i=0; i<argc; i++) {
    int l=strlen(argv[i]);
    if( (l>5) && !strcmp( &(argv[i][l-5]), flml_extension)) {
      flml_file=argv[i];
      break;
    }
  }
  if (flml_file) {
    string my_PETSc_options="-prns_flml ";
    my_PETSc_options+= flml_file;
    // see if next argument is a valid fieldname
    // but only if not already in the PETSc options database
    ierr = PetscOptionsHasName("prns_","-field",&flg);
    if( !flg && (i+1<argc) && (argv[i+1][0]!='-') ) {
      my_PETSc_options+= " -prns_field " + string(argv[i+1]);
    }
    ierr = PetscOptionsInsertString( my_PETSc_options.c_str() );
  }
  
  // -l option needs to be dealt with in c++ already
  ierr = PetscOptionsHasName("","-l",&flg);
  if (flg) {
    int rank = 0;
#ifdef HAVE_MPI
    if(MPI::Is_initialized()){
      rank = MPI::COMM_WORLD.Get_rank();
    }
#endif
    ostringstream buffer;
    buffer << "petsc_readnsolve.log-" << rank;
    if(freopen(buffer.str().c_str(), "w", stdout) == NULL){
      cerr << "Failed to redirect stdout" << endl;
      exit(-1);
    }
    buffer.str("");
    buffer << "petsc_readnsolve.err-" << rank;
    if(freopen(buffer.str().c_str(), "w", stderr) == NULL){
      cerr << "Failed to redirect stderr" << endl;
      exit(-1);
    }
    buffer.str("");
  }
}

int main(int argc, char **argv){

#ifdef HAVE_MPI
  // This must be called before we process any arguments
  MPI::Init(argc,argv);

  // Undo some MPI init shenanigans
  chdir(getenv("PWD"));
#endif

#ifdef HAVE_PETSC
  static char help[] = "Use -help to see the help.\n\n";
  PetscErrorCode ierr = PetscInitialize(&argc, &argv, NULL, help);
  // PetscInitializeFortran needs to be called when initialising PETSc from C, but calling it from Fortran
  // This sets all kinds of objects such as PETSC_NULL_OBJECT, PETSC_COMM_WORLD, etc., etc.
  ierr = PetscInitializeFortran();
  
  usage(argc, argv);
  
#ifdef HAVE_PYTHON
  // Initialize the Python Interpreter
  python_init_();
#endif
  
  petsc_readnsolve_();
  
#ifdef HAVE_PYTHON
  // Finalize the Python Interpreter
  python_end_();
#endif

  PetscFinalize();
#ifdef HAVE_MPI
  MPI::Finalize();
#endif
 
  return 0;
#else
  cerr << "ERROR: Not configured with PETSc, so petsc_readnsolve is not gonna work!" << endl; 
  return 1;
#endif

}