source: issm/trunk/src/c/classes/Dakota/IssmDirectApplicInterface.h@ 27232

Last change on this file since 27232 was 27232, checked in by Mathieu Morlighem, 3 years ago

merged trunk-jpl and trunk for revision 27230

File size: 5.6 KB
Line 
1/*!\file: IssmDirectApplicInterface.* This code is only valid for Dakota versions lower than 5!
2 *
3 * \brief: derived DirectApplicInterface class declaration and implementation, taylored to the ISSM cores.
4 * This class is registered into the interface database of Dakota, and is used to directly call ISSM cores
5 * from Dakota.
6 *
7 * This routine helps running ISSM and Dakota in library mode, for Dakota versions that are <=5, and which
8 * do not really support parallelism. In library mode, Dakota does not
9 * run as an execuatble. Its capabilities are linked into the ISSM software, and ISSM calls dakota routines
10 * directly from the dakota library. dakota_core.cpp is the code that is in charge of calling those routines.
11 *
12 * Prior to versions 6 and more, Dakota had its own way of running in parallel (for embarassingly parallel jobs).
13 * We do not want that, as ISSM knows exactly how to run "really parallel" jobs that use all CPUS. To bypass Dakota's parallelism,
14 * we overloaded the constructor for the parallel library (see the Dakota patch in the externalpackages/dakota
15 * directory). This overloaded constructor fires up Dakota serially on CPU 0 only! We take care of broadcasting
16 * to the other CPUS, hence ISSM is running in parallel, and Dakota serially on CPU0.
17 *
18 * Now, how does CPU 0 drive all other CPUS to carry out sensitivity analysese? By synchronizing its call to
19 * our ISSM cores (stressbalance_core, thermal_core, transient_core, etc ...) on CPU 0 with all other CPUS.
20 * This explains the structure of dakota_core.cpp, where cpu 0 runs Dakota, the Dakota pluggin fires up DakotaSpawnCore.cpp,
21 * while the other CPUS are waiting for a broadcast from CPU0, once they get it, they also fire up
22 * DakotaSpawnCore. In the end, DakotaSpawnCore is fired up on all CPUS, with CPU0 having Dakota inputs, that it will
23 * broacast to other CPUS.
24 *
25 * Now, how does dakota call the DakotaSpawnCore routine? The DakotaSpawnCore is embedded into the IssmDirectApplicInterface object
26 * which is derived from the Direct Interface Dakota objct. This is the only way to run Dakota in library
27 * mode (see their developper guide for more info). Dakota registers the IssmDirectApplicInterface object into its own
28 * database, and calls on the embedded DakotaSpawnCore from CPU0.
29 *
30 */
31
32/*Issm Configuration: {{{*/
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#else
36#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
37#endif
38/*}}}*/
39
40#if !defined(_WRAPPERS_) && defined(_HAVE_DAKOTA_) && (_DAKOTA_MAJOR_ <= 5) //this only works for Dakota <=5, which had no effective parallel capabilities yet.
41
42/*Dakota include files:{{{*/
43#if (_DAKOTA_MAJOR_ < 5 || (_DAKOTA_MAJOR_ == 5 && _DAKOTA_MINOR_ < 3))
44#include <DirectApplicInterface.H>
45#include <DakotaResponse.H>
46#include <ParamResponsePair.H>
47#include <system_defs.h>
48#include <ProblemDescDB.H>
49#include <ParallelLibrary.H>
50#else
51#include <DirectApplicInterface.hpp>
52#include <DakotaResponse.hpp>
53#include <ParamResponsePair.hpp>
54#include <ProblemDescDB.hpp>
55#include <ParallelLibrary.hpp>
56#endif
57/*}}}*/
58
59int DakotaSpawnCore(double* d_responses, int d_numresponses, double* d_variables, char** d_variables_descriptors,int d_numvariables, void* void_femmodel,int counter);
60
61/*IssmDirectApplicInterface class */
62namespace SIM {
63 class IssmDirectApplicInterface: public Dakota::DirectApplicInterface{
64 public:
65 /*these fields are used by core solutions: */
66 void *femmodel;
67 int counter;
68 /*Constructors/Destructors*/
69 IssmDirectApplicInterface(const Dakota::ProblemDescDB& problem_db,void* in_femmodel):Dakota::DirectApplicInterface(problem_db){/*{{{*/
70 femmodel = in_femmodel;
71 counter = 0;
72 }/*}}}*/
73 ~IssmDirectApplicInterface(){/*{{{*/
74 /* Virtual destructor handles referenceCount at Interface level. */
75 }/*}}}*/
76 protected:
77 /*execute the input filter portion of a direct evaluation invocation*/
78 //int derived_map_if(const Dakota::String& if_name);
79 /*execute an analysis code portion of a direct evaluation invocation*/
80 int derived_map_ac(const Dakota::String& driver){/*{{{*/
81
82 int i;
83 IssmDouble* variables=NULL;
84 char** variable_descriptors=NULL;
85 char* variable_descriptor=NULL;
86 IssmDouble* responses=NULL;
87
88 /*increae counter: */
89 counter++;
90
91 /*Before launching analysis, we need to transfer the dakota inputs into Issm
92 *readable variables: */
93
94 /*First, the variables: */
95 variables=xNew<IssmDouble>(numACV);
96 for(i=0;i<numACV;i++){
97 variables[i]=xC[i];
98 }
99 /*The descriptors: */
100 variable_descriptors=xNew<char*>(numACV);
101 for(i=0;i<numACV;i++){
102 std::string label=xCLabels[i];
103 variable_descriptor=xNew<char>(strlen(label.c_str())+1);
104 memcpy(variable_descriptor,label.c_str(),(strlen(label.c_str())+1)*sizeof(char));
105
106 variable_descriptors[i]=variable_descriptor;
107 }
108
109 /*Initialize responses: */
110 responses=xNewZeroInit<IssmDouble>(numFns);
111
112 /*run core solution: */
113 DakotaSpawnCore(responses,numFns, variables,variable_descriptors,numACV,femmodel,counter);
114
115 /*populate responses: */
116 for(i=0;i<numFns;i++){
117 fnVals[i]=responses[i];
118 }
119
120 /*Free resources:*/
121 xDelete<IssmDouble>(variables);
122 for(i=0;i<numACV;i++){
123 variable_descriptor=variable_descriptors[i];
124 xDelete<char>(variable_descriptor);
125 }
126 xDelete<char*>(variable_descriptors);
127 xDelete<IssmDouble>(responses);
128
129 return 0;
130 }/*}}}*/
131 /*execute the output filter portion of a direct evaluation invocation*/
132 //int derived_map_of(const Dakota::String& of_name);
133 /*add for issm: */
134 int GetCounter(){/*{{{*/
135 return counter;
136 }/*}}}*/
137 private:
138 };
139}
140#endif
Note: See TracBrowser for help on using the repository browser.