92 const unsigned int localNum = itsBunch->
getLocalNum();
93 for (
unsigned int i = 0; i < localNum; ++i) {
94 itsBunch->
R[i] = refToLocalCSTrafo.
transformTo(itsBunch->
R[i]);
95 itsBunch->
P[i] = refToLocalCSTrafo.
rotateTo(itsBunch->
P[i]);
99 msg <<
"Bunch before undulator in local coordinate system: " <<
endl;
100 itsBunch->
print(msg);
102 MITHRA::helloMessage();
105 MITHRA::BunchInitialize bunchInit;
106 bunchInit.bunchType_ =
"other";
107 bunchInit.numberOfParticles_ = itsBunch->
getTotalNum();
108 bunchInit.cloudCharge_ =
110 bunchInit.initialGamma_ = itsBunch->
get_gamma();
111 for (
unsigned int d = 0; d < 3; ++d)
112 bunchInit.initialDirection_[d] = itsBunch->
get_pmean()[d];
115 bunch.bunchInit_.push_back(bunchInit);
117 msg <<
"Bunch parameters have been transferred to the full-wave solver." <<
endl;
119 MITHRA::Undulator undulator;
120 undulator.k_ =
getK();
124 double lFringe = 2 * undulator.lu_;
126 std::vector<MITHRA::Undulator> undulators;
127 undulators.push_back(undulator);
128 msg <<
"Undulator parameters have been transferred to the full-wave solver." <<
endl;
132 mesh.lengthScale_ = 1.0;
133 mesh.timeScale_ = 1.0;
134 mesh.meshCenter_ = MITHRA::FieldVector<double>(0.0);
139 if (mesh.totalTime_ == 0)
140 mesh.totalDist_ = lFringe + undulator.lu_ * undulator.length_;
142 mesh.spaceCharge_ =
true;
143 mesh.optimizePosition_ =
true;
144 msg <<
"Mesh parameters have been transferred to the full-wave solver." <<
endl;
148 std::vector<MITHRA::ExtField> externalFields;
149 std::vector<MITHRA::FreeElectronLaser> FELs;
153 std::list<std::string> jobFile = MITHRA::read_file(
fname_m.c_str());
154 MITHRA::cleanJobFile(jobFile);
155 MITHRA::ParseDarius parser(jobFile, mesh, bunch, seed, undulators, externalFields, FELs);
156 parser.setJobParameters();
159 MITHRA::FdTdSC solver(mesh, bunch, seed, undulators, externalFields, FELs);
162 MITHRA::Charge charge;
164 for (
unsigned int i = 0; i < localNum; ++i) {
165 for (
unsigned int d = 0; d < 3; ++d) {
166 charge.rnp[d] = itsBunch->
R[i][d];
167 charge.gbnp[d] = itsBunch->
P[i][d];
169 solver.chargeVectorn_.push_back(charge);
171 itsBunch->
destroy(localNum, 0,
true);
172 msg <<
"Particles have been transferred to the full-wave solver." <<
endl;
178 for (
unsigned int i = 0; i < undulators.size(); i++) {
179 undulators[i].show();
181 for (
unsigned int i = 0; i < externalFields.size(); i++) {
182 externalFields[i].show();
186 timeval simulationStart;
187 gettimeofday(&simulationStart,
nullptr);
191 timeval simulationEnd;
192 gettimeofday(&simulationEnd,
nullptr);
193 double deltaTime = (simulationEnd.tv_usec - simulationStart.tv_usec) *
Units::us2s;
194 deltaTime += (simulationEnd.tv_sec - simulationStart.tv_sec);
195 msg <<
"::: Total full wave simulation time [seconds] = " << deltaTime <<
endl;
200 for (
auto iter = solver.chargeVectorn_.begin(); iter != solver.chargeVectorn_.end(); iter++) {
201 zMin = std::min(zMin, iter->rnp[2]);
203 allreduce(&zMin, 1, std::less<double>());
205 const double gammaBeta = solver.gamma_ * solver.beta_;
206 const double factor = gammaBeta * solver.c0_ * (solver.timeBunch_ + solver.dt_) + lFringe;
207 for (
auto iter = solver.chargeVectorn_.begin(); iter != solver.chargeVectorn_.end(); iter++) {
208 double dist = zMin - iter->rnp[2];
210 iter->rnp[2] = solver.gamma_ * iter->rnp[2] + factor;
212 solver.gamma_ * iter->gbnp[2] + gammaBeta * std::sqrt(1 + iter->gbnp.norm2());
214 double gammaParticle = std::sqrt(1 + iter->gbnp.norm2());
215 iter->rnp[0] += iter->gbnp[0] / gammaParticle * dist * gammaBeta;
216 iter->rnp[1] += iter->gbnp[1] / gammaParticle * dist * gammaBeta;
217 iter->rnp[2] += iter->gbnp[2] / gammaParticle * dist * gammaBeta;
222 solver.gamma_ * (solver.time_ + solver.beta_ / solver.c0_ * (zMin - bunch.zu_));
225 msg <<
"Transferring particles back to OPAL bunch." <<
endl;
226 itsBunch->
create(solver.chargeVectorn_.size());
227 const double dt = itsBunch->
getdT();
228 const unsigned int newLocalNum = itsBunch->
getLocalNum();
229 std::list<MITHRA::Charge>::iterator iter = solver.chargeVectorn_.begin();
230 for (
unsigned int i = 0; i < newLocalNum; ++i) {
231 for (
unsigned int d = 0; d < 3; ++d) {
232 itsBunch->
R[i][d] = iter->rnp[d];
233 itsBunch->
P[i][d] = iter->gbnp[d];
236 itsBunch->
dt[i] = dt;
239 itsBunch->
setT(itsBunch->
getT() + mesh.totalTime_);
243 for (
unsigned int i = 0; i < newLocalNum; ++i) {
244 itsBunch->
R[i] = localToRefCSTrafo.
transformTo(itsBunch->
R[i]);
245 itsBunch->
P[i] = localToRefCSTrafo.
rotateTo(itsBunch->
P[i]);
254 msg <<
"Bunch after undulator in reference coordinate system: " <<
endl;
255 itsBunch->
print(msg);