-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtangentialSimulation.cpp
More file actions
172 lines (148 loc) · 7.03 KB
/
tangentialSimulation.cpp
File metadata and controls
172 lines (148 loc) · 7.03 KB
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include "std_include.h"
#include <tclap/CmdLine.h>
#include "profiler.h"
#include "noiseSource.h"
#include "triangulatedMeshSpace.h"
#include "tangentialOpenMeshSpace.h"
#include "simulation.h"
#include "gradientDescent.h"
#include "fireMinimization.h"
#include "velocityVerletNVE.h"
#include "simpleModel.h"
#include "gaussianRepulsion.h"
#include "harmonicRepulsion.h"
#include "vectorValueDatabase.h"
#include "simpleModelDatabase.h"
#include "cellListNeighborStructure.h"
void getFlatVectorOfPositions(shared_ptr<simpleModel> model, vector<double> &pos)
{
int N = model->N;
model->fillEuclideanLocations();
pos.resize(3*N);
for (int ii = 0; ii < N; ++ii)
{
double3 p = model->euclideanLocations[ii];
pos[3*ii+0] = p.x;
pos[3*ii+1] = p.y;
pos[3*ii+2] = p.z;
}
};
using namespace TCLAP;
int main(int argc, char*argv[])
{
//First, we set up a basic command line parser with some message and version
CmdLine cmd("simulations in curved space!",' ',"V0.9");
//define the various command line strings that can be passed in...
ValueArg<int> programBranchSwitchArg("z","programBranchSwitch","an integer controlling program branch",false,0,"int",cmd);
ValueArg<int> particleNumberSwitchArg("n","number","number of particles to simulate",false,20,"int",cmd);
ValueArg<int> iterationsArg("i","iterations","number of performTimestep calls to make",false,1000,"int",cmd);
ValueArg<int> saveFrequencyArg("s","saveFrequency","how often a file gets updated",false,100,"int",cmd);
ValueArg<string> meshSwitchArg("m","meshSwitch","filename of the mesh you want to load",false,"../exampleMeshes/torus_isotropic_remesh.off","string",cmd);
ValueArg<double> areaFractionArg("a","areaFraction","degree of coverage you want f",false,1.,"double",cmd);
ValueArg<double> deltaTArg("e","dt","timestep size",false,.01,"double",cmd);
ValueArg<double> temperatureArg("t","T","temperature to set",false,.2,"double",cmd);
SwitchArg reproducibleSwitch("r","reproducible","reproducible random number generation", cmd, true);
SwitchArg dangerousSwitch("d","dangerousMeshes","meshes where submeshes are dangerous", cmd, false);
SwitchArg verboseSwitch("v","verbose","output more things to screen ", cmd, false);
//parse the arguments
cmd.parse( argc, argv );
//define variables that correspond to the command line parameters
int programBranch = programBranchSwitchArg.getValue();
int N = particleNumberSwitchArg.getValue();
int maximumIterations = iterationsArg.getValue();
int saveFrequency = saveFrequencyArg.getValue();
string meshName = meshSwitchArg.getValue();
double dt = deltaTArg.getValue();
double areaFraction = areaFractionArg.getValue();
double temperature = temperatureArg.getValue();
bool verbose= verboseSwitch.getValue();
bool reproducible = reproducibleSwitch.getValue();
bool dangerous = dangerousSwitch.getValue(); //not used right now
shared_ptr<tangentialOpenMeshSpace> meshSpace=make_shared<tangentialOpenMeshSpace>();
meshSpace->loadMeshFromFile(meshName,verbose);
meshSpace->useSubmeshingRoutines(false);
double area = totalArea(meshSpace->surface);
double maximumInteractionRange = 2*sqrt(areaFraction*area/(N*M_PI)); //set maximum interaction range via 2-D disk areas
if(programBranch >=0)
meshSpace->useSubmeshingRoutines(true,maximumInteractionRange,dangerous);
shared_ptr<simpleModel> configuration=make_shared<simpleModel>(N);
configuration->setVerbose(verbose);
configuration->setSpace(meshSpace);
//set up the cellListNeighborStructure, which needs to know how large the mesh is
shared_ptr<cellListNeighborStructure> cellList = make_shared<cellListNeighborStructure>(meshSpace->minVertexPosition,meshSpace->maxVertexPosition,maximumInteractionRange);
if(programBranch >= 0)
configuration->setNeighborStructure(cellList);
//for testing, just initialize particles randomly in a small space. Similarly, set random velocities in the tangent plane
noiseSource noise(reproducible);
configuration->setRandomParticlePositions(noise);
configuration->setMaxwellBoltzmannVelocities(noise,temperature);
//shared_ptr<gaussianRepulsion> pairwiseForce = make_shared<gaussianRepulsion>(1.0,.5);
shared_ptr<harmonicRepulsion> pairwiseForce = make_shared<harmonicRepulsion>(1.0,maximumInteractionRange);//stiffness and sigma. this is a monodisperse setting
pairwiseForce->setModel(configuration);
shared_ptr<simulation> simulator=make_shared<simulation>();
simulator->setConfiguration(configuration);
simulator->addForce(pairwiseForce);
shared_ptr<gradientDescent> energyMinimizer=make_shared<gradientDescent>(dt);
shared_ptr<fireMinimization> energyMinimizerFire=make_shared<fireMinimization>();
shared_ptr<velocityVerletNVE> nve=make_shared<velocityVerletNVE>(dt);
if(programBranch >=2)
{
cout <<"running nve" << endl;
nve->setModel(configuration);
simulator->addUpdater(nve,configuration);
}
else if (programBranch >=1)
{
cout <<"running gradient descent" << endl;
energyMinimizer->setModel(configuration);
simulator->addUpdater(energyMinimizer,configuration);
}
else
{
cout <<"running FIRE minimization" << endl;
energyMinimizerFire->setModel(configuration);
simulator->addUpdater(energyMinimizerFire,configuration);
}
profiler timer("various parts of the code");
/*
vector<double> posToSave;
getFlatVectorOfPositions(configuration,posToSave);
vectorValueDatabase vvdat(posToSave.size(),"./testTrajectory.h5",fileMode::replace);
vvdat.writeState(posToSave,0);
*/
//by default, the simpleModelDatabase will save euclidean positions, mesh positions (barycentric + faceIdx), and particle velocities. See constructor for saving forces and/or particle types as well
simpleModelDatabase saveState(N,"./tangentialTestModelDatabase.h5",fileMode::replace);
saveState.writeState(configuration,0.0);
for (int ii = 0; ii < maximumIterations; ++ii)
{
timer.start();
simulator->performTimestep();
timer.end();
if(ii%saveFrequency == saveFrequency-1)
{
/*
getFlatVectorOfPositions(configuration,posToSave);
vvdat.writeState(posToSave,dt*ii);
*/
saveState.writeState(configuration,dt*ii);
if(programBranch ==1)
{
double fNorm,fMax;
fNorm = energyMinimizer->getForceNorm();
fMax = energyMinimizer->getMaxForce();
printf("step %i fN %g fM %g\n",ii,fNorm,fMax);
}
else
printf("step %i \n",ii);
}
}
if(programBranch ==0)
{
double fNorm,fMax;
fNorm = energyMinimizerFire->getForceNorm();
fMax = energyMinimizerFire->getMaxForce();
printf("fN %g fM %g\n",fNorm,fMax);
}
timer.print();
return 0;
};