-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathchef_phasta_sam_adaptLoop_ramdisk.cc
151 lines (140 loc) · 4.32 KB
/
chef_phasta_sam_adaptLoop_ramdisk.cc
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
#include "chefPhasta.h"
#include <PCU.h>
#include <chef.h>
#include <phasta.h>
#include <phstream.h>
#include <sam.h>
#include <apfMDS.h>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
/** \file chef_phasta_sam_adaptLoop_ramdisk.cc
\brief Example file-based driver for adaptive loops using a ramdisk
\remark Runs Chef and then PHASTA until the user-specified maximum
PHASTA time step is reached. Size fields to drive adaptation
are defined using SAM from
<a href=https://github.com/SCOREC/core>core</a>.
This example also demonstrates the use of the fine grained
chef.h and phasta.h APIs.
*/
namespace {
void printElapsedTime(const char* key, double s) {
if( !PCU_Comm_Self() )
fprintf(stderr, "%s elapsed time %.3f\n", key, PCU_Time()-s);
}
void freeMesh(apf::Mesh* m) {
m->destroyNative();
apf::destroyMesh(m);
}
void mychdir(const char* path) {
const int fail = chdir(path);
if(fail) {
fprintf(stderr, "ERROR failed to change to %s dir... exiting\n", path);
exit(1);
}
}
void mychdir(int step) {
std::stringstream path;
path << step;
string s = path.str();
const int fail = chdir(s.c_str());
if(fail) {
fprintf(stderr, "ERROR failed to change to %d dir... exiting\n", step);
exit(1);
}
}
std::string makeMeshName(int step) {
std::stringstream meshname;
meshname << "bz2:" << "t" << step << "p" << PCU_Comm_Peers() << "_.smb";
return meshname.str();
}
std::string makeRestartName() {
std::stringstream restartname;
restartname << PCU_Comm_Peers() << "-procs_case/restart";
return restartname.str();
}
apf::Field* getField(apf::Mesh* m) {
/* if the value of the fldIdx'th index from the fldName
* field is greater than fldLimit then multiply the current
* isotropic mesh size at the vertex by szFactor */
const unsigned fldIdx = 5;
const double fldLimit = 1e-6;
const double szFactor = 0.5;
const char* fldName = "errors";
return sam::errorThreshold(m,fldName,fldIdx,fldLimit,szFactor);
}
void setupChef(ph::Input& ctrl, int step) {
//don't split or tetrahedronize
ctrl.splitFactor = 1;
ctrl.tetrahedronize = 0;
ctrl.timeStepNumber = step;
ctrl.solutionMigration = 1;
if(step>1) {
if(!PCU_Comm_Self()) {
fprintf(stderr, "STATUS error based adapt %d\n", step);
fprintf(stderr, "STATUS ctrl.attributeFileName %s step %d\n",
ctrl.attributeFileName.c_str(), step);
}
ctrl.adaptStrategy = 1; //error field adapt
ctrl.adaptFlag = 1;
}
ctrl.outMeshFileName = makeMeshName(step);
ctrl.restartFileName = makeRestartName();
}
}
int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
PCU_Comm_Init();
PCU_Protect();
if( argc != 6 ) {
if(!PCU_Comm_Self())
fprintf(stderr, "Usage: %s <maxTimeStep> <ramdisk path> <solver.inp> <input.config> <adapt.inp>\n",argv[0]);
exit(EXIT_FAILURE);
}
int maxStep = atoi(argv[1]);
const char* ramdisk = argv[2];
const char* solverinp = argv[3];
const char* inputcfg = argv[4];
const char* adaptinp = argv[5];
double start = PCU_Time();
gmi_model* g = 0;
apf::Mesh2* m = 0;
mychdir(ramdisk);
ph::Input ctrl;
ctrl.load(adaptinp);
ctrl.outMeshFileName = makeMeshName(0);
chefPhasta::initModelers();
chef::cook(g,m,ctrl);
freeMesh(m); m = NULL;
phSolver::Input inp(solverinp,inputcfg);
int step = 0;
do {
double stepStart = PCU_Time();
ctrl.meshFileName = makeMeshName(step);
step = phasta(inp);
assert(step >= 0);
if(!PCU_Comm_Self())
fprintf(stderr, "STATUS ran to step %d\n", step);
if( step >= maxStep )
break;
apf::Mesh2* m = apf::loadMdsMesh(ctrl.modelFileName.c_str(),
ctrl.meshFileName.c_str());
setupChef(ctrl,step);
chef::readAndAttachFields(ctrl,m);
apf::Field* szFld = getField(m);
assert(szFld);
chef::adapt(m,szFld);
apf::destroyField(szFld);
chef::balance(ctrl,m);
chef::preprocess(m,ctrl);
freeMesh(m); m = NULL;
mychdir(step);
printElapsedTime("endOfStep", stepStart);
printElapsedTime("total", start);
} while( step < maxStep );
chefPhasta::finalizeModelers();
PCU_Comm_Free();
MPI_Finalize();
}