Commit c1f9af37 authored by albajacas_a's avatar albajacas_a

Merge branch '535-opal-fel-mithra-integration' into 'master'

Resolve "OPAL-FEL (MITHRA integration)"

See merge request !361
parents 1fbbeeaf cb35f849
......@@ -208,7 +208,7 @@ option (ENABLE_OPAL_FEL "Enable OPAL FEL" OFF)
if (ENABLE_OPAL_FEL)
message (STATUS "Enable OPAL FEL: " ${ENABLE_OPAL_FEL})
find_package (MITHRA MODULE REQUIRED)
add_definitions (-DOPAL_FEL)
add_definitions (-DENABLE_OPAL_FEL)
endif()
option (DBG_SCALARFIELD "Enable dump of scalar field rho_m" OFF)
......
......@@ -3,23 +3,47 @@
# https://github.com/aryafallahi/mithra
#
# MITHRA_INCLUDE_DIR
# MITHRA_LIBRARY_DIR
# MITHRA_FOUND
find_path (MITHRA_INCLUDE_DIR mithra/classes.hh
HINTS $ENV{MITHRA_INCLUDE_PATH} $ENV{MITHRA_INCLUDE_DIR} $ENV{MITHRA_PREFIX}/include $ENV{MITHRA_DIR}/include $ENV{MITHRA}/include
PATHS ENV C_INCLUDE_PATH CPLUS_INCLUDE_PATH
find_path (MITHRA_INCLUDE_DIR mithra/classes.h
HINTS $ENV{MITHRA_INCLUDE_DIR} $ENV{MITHRA_INCLUDE_PATH} $ENV{MITHRA_PREFIX}/include $ENV{MITHRA}/include
)
if (MITHRA_INCLUDE_DIR)
find_path (MITHRA_LIBRARY_DIR libmithra.a
HINTS $ENV{MITHRA_LIBRARY_DIR} $ENV{MITHRA_LIBRARY_PATH} $ENV{MITHRA_PREFIX}/lib $ENV{MITHRA}/lib
)
if (MITHRA_INCLUDE_DIR AND MITHRA_LIBRARY_DIR)
set (MITHRA_FOUND "YES")
endif ()
if (MITHRA_FOUND)
if (NOT MITHRA_FIND_QUIETLY)
message (STATUS "Found MITHRA include dir: ${MITHRA_INCLUDE_DIR}")
message (STATUS "Found MITHRA library dir: ${MITHRA_LIBRARY_DIR}")
endif ()
else (MITHRA_FOUND)
if (MITHRA_FIND_REQUIRED)
if (NOT MITHRA_INCLUDE_DIR)
message (WARNING
"MITHRA include directory was not found! "
"Make sure that MITHRA is compiled and that "
"the directory mithra/include/mithra has been automatically created. "
"Also make sure that at least one of the following "
"environment variables is set: "
"MITHRA_INCLUDE_DIR, MITHRA_INCLUDE_PATH, MITHRA_PREFIX, or MITHRA.")
endif ()
if (NOT MITHRA_LIBRARY_DIR)
message (WARNING
"MITHRA library was not found! "
"Make sure that MITHRA is compiled and that "
"the directory mithra/lib has been automatically created. "
"Also make sure that at least one of the following "
"environment variables is set: "
"MITHRA_LIBRARY_DIR, MITHRA_LIBRARY_PATH, MITHRA_PREFIX, or MITHRA.")
endif ()
message (STATUS "MITHRA can be downloaded and compiled from https://github.com/aryafallahi/mithra.git")
message (FATAL_ERROR "Could not find MITHRA!")
endif (MITHRA_FIND_REQUIRED)
endif (MITHRA_FOUND)
......@@ -51,6 +51,10 @@
#include "Structure/BoundaryGeometry.h"
#include "AbsBeamline/Monitor.h"
#ifdef ENABLE_OPAL_FEL
#include "BeamlineCore/UndulatorRep.h"
#endif
class PartData;
ParallelTTracker::ParallelTTracker(const Beamline &beamline,
......@@ -572,6 +576,9 @@ void ParallelTTracker::computeExternalFields(OrbitThreader &oth) {
IpplTimings::stopTimer(fieldEvaluationTimer_m);
computeWakefield(elements);
#ifdef ENABLE_OPAL_FEL
computeUndulator(elements);
#endif
computeParticleMatterInteraction(elements, oth);
reduce(locPartOutOfBounds, globPartOutOfBounds, OpOrAssign());
......@@ -598,6 +605,30 @@ void ParallelTTracker::computeExternalFields(OrbitThreader &oth) {
}
}
#ifdef ENABLE_OPAL_FEL
void ParallelTTracker::computeUndulator(IndexMap::value_t &elements) {
// Check if bunch has entered undulator field.
UndulatorRep* und;
IndexMap::value_t::const_iterator it = elements.begin();
for (; it != elements.end(); ++ it)
if ((*it)->getType() == ElementBase::UNDULATOR) {
und = dynamic_cast<UndulatorRep*>(it->get());
if (!und->getHasBeenSimulated())
break;
}
if (it == elements.end())
return;
// Apply MITHRA full wave solver for undulator.
CoordinateSystemTrafo refToLocalCSTrafo = (itsOpalBeamline_m.getMisalignment((*it)) *
(itsOpalBeamline_m.getCSTrafoLab2Local((*it)) * itsBunch_m->toLabTrafo_m));
und->apply(itsBunch_m, refToLocalCSTrafo);
evenlyDistributeParticles();
}
#endif
void ParallelTTracker::computeWakefield(IndexMap::value_t &elements) {
bool hasWake = false;
WakeFunction *wfInstance;
......@@ -1377,4 +1408,4 @@ void ParallelTTracker::evenlyDistributeParticles() {
if (requests.size() > 0) {
MPI_Waitall(requests.size(), &(requests[0]), MPI_STATUSES_IGNORE);
}
}
}
\ No newline at end of file
......@@ -39,8 +39,8 @@
#include "AbsBeamline/Corrector.h"
#include "AbsBeamline/Degrader.h"
#include "AbsBeamline/Drift.h"
#include "AbsBeamline/FlexibleCollimator.h"
#include "AbsBeamline/ElementBase.h"
#include "AbsBeamline/FlexibleCollimator.h"
#include "AbsBeamline/Marker.h"
#include "AbsBeamline/Monitor.h"
#include "AbsBeamline/Multipole.h"
......@@ -49,10 +49,14 @@
#include "AbsBeamline/RBend.h"
#include "AbsBeamline/RBend3D.h"
#include "AbsBeamline/RFCavity.h"
#include "AbsBeamline/TravelingWave.h"
#include "AbsBeamline/SBend.h"
#include "AbsBeamline/Septum.h"
#include "AbsBeamline/Solenoid.h"
#include "AbsBeamline/TravelingWave.h"
#ifdef ENABLE_OPAL_FEL
#include "AbsBeamline/Undulator.h"
#endif
#include "Beamlines/Beamline.h"
#include "Elements/OpalBeamline.h"
......@@ -142,7 +146,12 @@ public:
/// Apply the algorithm to a RFCavity.
virtual void visitTravelingWave(const TravelingWave &);
#ifdef ENABLE_OPAL_FEL
/// Apply the algorithm to an Undulator.
virtual void visitUndulator(const Undulator &);
#endif
/// Apply the algorithm to a SBend.
virtual void visitSBend(const SBend &);
......@@ -151,7 +160,7 @@ public:
/// Apply the algorithm to a Solenoid.
virtual void visitSolenoid(const Solenoid &);
/// Apply the algorithm to a Solenoid.
virtual void visitSource(const Source &);
......@@ -247,6 +256,9 @@ private:
void computeExternalFields(OrbitThreader &oth);
void computeWakefield(IndexMap::value_t &elements);
void computeParticleMatterInteraction(IndexMap::value_t elements, OrbitThreader &oth);
#ifdef ENABLE_OPAL_FEL
void computeUndulator(IndexMap::value_t &elements);
#endif
void computeSpaceChargeFields(unsigned long long step);
// void prepareOpalBeamlineSections();
void dumpStats(long long step, bool psDump, bool statDump);
......@@ -338,6 +350,11 @@ inline void ParallelTTracker::visitTravelingWave(const TravelingWave &as) {
itsOpalBeamline_m.visit(as, *this, itsBunch_m);
}
#ifdef ENABLE_OPAL_FEL
inline void ParallelTTracker::visitUndulator(const Undulator &u) {
itsOpalBeamline_m.visit(u, *this, itsBunch_m);
}
#endif
inline void ParallelTTracker::visitSBend(const SBend &bend) {
itsOpalBeamline_m.visit(bend, *this, itsBunch_m);
......
......@@ -145,6 +145,11 @@ target_link_libraries( opal
${CMAKE_DL_LIBS}
)
if (ENABLE_OPAL_FEL)
include_directories (${MITHRA_INCLUDE_DIR})
target_link_libraries(libOPAL ${MITHRA_LIBRARY_DIR}/libmithra.a)
endif()
install (TARGETS ${TEST_EXE} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
install (TARGETS opal RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
install (TARGETS libOPAL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
......
......@@ -69,6 +69,9 @@ class Solenoid;
class Source;
class Stripper;
class TravelingWave;
#ifdef ENABLE_OPAL_FEL
class Undulator;
#endif
class VariableRFCavity;
class VariableRFCavityFringeField;
class VerticalFFAMagnet;
......@@ -156,6 +159,11 @@ public:
/// Apply the algorithm to a RF cavity.
virtual void visitTravelingWave(const TravelingWave &) = 0;
#ifdef ENABLE_OPAL_FEL
/// Apply the algorithm to an undulator space.
virtual void visitUndulator(const Undulator &) = 0;
#endif
/// Apply the algorithm to a sector bend.
virtual void visitSBend(const SBend &) = 0;
......
......@@ -43,12 +43,6 @@ set (_SRCS
VerticalFFAMagnet.cpp
)
include_directories (
${CMAKE_CURRENT_SOURCE_DIR}
)
add_opal_sources (${_SRCS})
set (HDRS
AttributeSet.h
BeamlineVisitor.h
......@@ -92,4 +86,15 @@ set (HDRS
VerticalFFAMagnet.h
)
if (ENABLE_OPAL_FEL)
list (APPEND _SRCS Undulator.cpp)
list (APPEND HDRS Undulator.h)
endif ()
include_directories (
${CMAKE_CURRENT_SOURCE_DIR}
)
add_opal_sources (${_SRCS})
install (FILES ${HDRS} DESTINATION "${CMAKE_INSTALL_PREFIX}/include/AbsBeamline")
......@@ -232,6 +232,10 @@ std::string ElementBase::getTypeString(ElementBase::ElementType type) {
return "Stripper";
case TRAVELINGWAVE:
return "TravelingWave";
#ifdef ENABLE_OPAL_FEL
case UNDULATOR:
return "Undulator";
#endif
case VARIABLERFCAVITY:
return "VariableRFCavity";
case ANY:
......
......@@ -132,6 +132,7 @@ public:
, SOURCE
, STRIPPER
, TRAVELINGWAVE
, UNDULATOR
, VARIABLERFCAVITY
, ANY};
......
......@@ -54,6 +54,10 @@
#include "AbsBeamline/Source.h"
#include "AbsBeamline/Stripper.h"
#ifdef ENABLE_OPAL_FEL
#include "AbsBeamline/Undulator.h"
#endif
#include "Beamlines/Beamline.h"
#include "Beamlines/FlaggedElmPtr.h"
......@@ -155,6 +159,11 @@ public:
/// Apply the algorithm to a RF cavity.
virtual void visitTravelingWave(const TravelingWave &);
#ifdef ENABLE_OPAL_FEL
/// Apply the algorithm to an undulator.
virtual void visitUndulator(const Undulator &);
#endif
/// Apply the algorithm to a sector bend.
virtual void visitSBend(const SBend &);
......@@ -342,6 +351,13 @@ void SpecificElementVisitor<ELEM>::visitTravelingWave(const TravelingWave &eleme
CastsTrait<ELEM, TravelingWave>::apply(allElementsOfTypeE, element);
}
#ifdef ENABLE_OPAL_FEL
template<class ELEM>
void SpecificElementVisitor<ELEM>::visitUndulator(const Undulator &element) {
CastsTrait<ELEM, Undulator>::apply(allElementsOfTypeE, element);
}
#endif
template<class ELEM>
void SpecificElementVisitor<ELEM>::visitSBend(const SBend &element) {
CastsTrait<ELEM, SBend>::apply(allElementsOfTypeE, element);
......
This diff is collapsed.
//
// Class Undulator
// Defines all the methods used by the Undulator element.
// The Undulator element uses a full wave solver from the
// MITHRA library, see <https://github.com/aryafallahi/mithra/>.
//
// Copyright (c) 2020, Arnau Albà, Paul Scherrer Institut, Villigen PSI, Switzerland
// All rights reserved.
//
// Implemented as part of the MSc thesis
// "Start-to-End Modelling of the AWA Micro-Bunched Electron Cooling POP-Experiment"
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#ifndef CLASSIC_Undulator_HH
#define CLASSIC_Undulator_HH
#include <string>
#include <vector>
#include "AbsBeamline/Component.h"
class Undulator : public Component {
public:
/// Constructor with given name.
explicit Undulator(const std::string& name);
Undulator();
Undulator(const Undulator& right);
virtual ~Undulator();
/// Apply visitor to Undulator.
virtual void accept(BeamlineVisitor&) const;
virtual void initialise(PartBunchBase<double, 3>* bunch, double& startField, double& endField);
void apply(PartBunchBase<double, 3>* itsBunch, CoordinateSystemTrafo const& refToLocalCSTrafo);
virtual void finalise();
virtual bool bends() const;
virtual ElementBase::ElementType getType() const;
virtual void getDimensions(double& zBegin, double& zEnd) const;
void setK(double k);
double getK() const;
void setLambda(double lambda);
double getLambda() const;
void setNumPeriods(unsigned int np);
unsigned int getNumPeriods() const;
void setAngle(double theta);
double getAngle() const;
void setFilename(const std::string& fname);
const std::string& getFilename() const;
void setMeshLength(const std::vector<double>& ml);
std::vector<double> getMeshLength() const;
void setMeshResolution(const std::vector<double>& mr);
std::vector<double> getMeshResolution() const;
void setTruncationOrder(unsigned int trunOrder);
unsigned int getTruncationOrder() const;
void setTotalTime(double tt);
double getTotalTime() const;
void setDtBunch(double dtb);
double getDtBunch() const;
void setHasBeenSimulated(bool hbs);
bool getHasBeenSimulated() const;
private:
/// The undulator parameter
double k_m;
/// Undulator period
double lambda_m;
/// Number of periods
unsigned int numPeriods_m;
/// Polarisation angle of the undulator field
double angle_m;
/// Mithra file with output information
std::string fname_m;
/// Size of computational domain
std::vector<double> meshLength_m;
/// Mesh dx, dy, dz
std::vector<double> meshResolution_m;
/// First or second order absorbing boundary conditions
unsigned int truncationOrder_m;
/// Total time to run undulator
double totalTime_m;
/// Time step for the bunch position update
double dtBunch_m;
/// Boolean to indicate whether this undulator has already been simulated
bool hasBeenSimulated_m;
// Not implemented.
void operator=(const Undulator&);
};
#endif // CLASSIC_Undulator_HH
......@@ -54,6 +54,10 @@
#include "AbsBeamline/VariableRFCavityFringeField.h"
#include "AbsBeamline/VerticalFFAMagnet.h"
#ifdef ENABLE_OPAL_FEL
#include "AbsBeamline/Undulator.h"
#endif
#include "Beamlines/Beamline.h"
#include "Beamlines/FlaggedElmPtr.h"
......@@ -180,6 +184,11 @@ void DefaultVisitor::visitTravelingWave(const TravelingWave &trw) {
applyDefault(trw);
}
#ifdef ENABLE_OPAL_FEL
void DefaultVisitor::visitUndulator(const Undulator &u) {
applyDefault(u);
}
#endif
void DefaultVisitor::visitSBend(const SBend &bend) {
applyDefault(bend);
......
......@@ -117,6 +117,11 @@ public:
/// Apply the algorithm to a RF cavity.
virtual void visitTravelingWave(const TravelingWave &);
#ifdef ENABLE_OPAL_FEL
/// Apply the algorithm to an undulator.
virtual void visitUndulator(const Undulator &);
#endif
/// Apply the algorithm to a sector bend.
virtual void visitSBend(const SBend &);
......
......@@ -28,12 +28,6 @@ set (_SRCS
YCorrectorRep.cpp
)
include_directories (
${CMAKE_CURRENT_SOURCE_DIR}
)
add_opal_sources (${_SRCS})
set (HDRS
BeamStrippingRep.h
CCollimatorRep.h
......@@ -65,4 +59,15 @@ set (HDRS
YCorrectorRep.h
)
if (ENABLE_OPAL_FEL)
list (APPEND _SRCS UndulatorRep.cpp)
list (APPEND HDRS UndulatorRep.h)
endif ()
include_directories (
${CMAKE_CURRENT_SOURCE_DIR}
)
add_opal_sources (${_SRCS})
install (FILES ${HDRS} DESTINATION "${CMAKE_INSTALL_PREFIX}/include/BeamlineCore")
//
// Class UndulatorRep
// Defines a concrete undulator/wiggler representation.
//
// Copyright (c) 2020, Arnau Albà, Paul Scherrer Institut, Villigen PSI, Switzerland
// All rights reserved.
//
// Implemented as part of the MSc thesis
// "Start-to-End Modelling of the AWA Micro-Bunched Electron Cooling POP-Experiment"
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#include "BeamlineCore/UndulatorRep.h"
#include "Channels/IndirectChannel.h"
// Attribute access table.
namespace {
struct Entry {
const char* name;
double (UndulatorRep::*get)() const;
void (UndulatorRep::*set)(double);
};
const Entry entries[] = {
{"L", &UndulatorRep::getElementLength, &UndulatorRep::setElementLength}, {0, 0, 0}};
} // namespace
UndulatorRep::UndulatorRep() : Undulator(), geometry(0.0) {
}
UndulatorRep::UndulatorRep(const UndulatorRep& right) : Undulator(right), geometry(right.geometry) {
}
UndulatorRep::UndulatorRep(const std::string& name) : Undulator(name), geometry(0.0) {
}
UndulatorRep::~UndulatorRep() {
}
ElementBase* UndulatorRep::clone() const {
return new UndulatorRep(*this);
}
Channel* UndulatorRep::getChannel(const std::string& aKey, bool create) {
for (const Entry* entry = entries; entry->name != 0; ++entry) {
if (aKey == entry->name) {
return new IndirectChannel<UndulatorRep>(*this, entry->get, entry->set);
}
}
return ElementBase::getChannel(aKey, create);
}
NullField& UndulatorRep::getField() {
return field;
}
const NullField& UndulatorRep::getField() const {
return field;
}
StraightGeometry& UndulatorRep::getGeometry() {
return geometry;
}
const StraightGeometry& UndulatorRep::getGeometry() const {
return geometry;
}
\ No newline at end of file
//
// Class UndulatorRep
// Defines a concrete undulator/wiggler representation.
//
// Copyright (c) 2020, Arnau Albà, Paul Scherrer Institut, Villigen PSI, Switzerland
// All rights reserved.
//
// Implemented as part of the MSc thesis
// "Start-to-End Modelling of the AWA Micro-Bunched Electron Cooling POP-Experiment"
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#ifndef CLASSIC_UndulatorRep_HH
#define CLASSIC_UndulatorRep_HH
#include "AbsBeamline/Undulator.h"
#include "BeamlineGeometry/StraightGeometry.h"
#include "Fields/NullField.h"
class UndulatorRep : public Undulator {
public:
/// Constructor with given name.
explicit UndulatorRep(const std::string& name);
UndulatorRep();
UndulatorRep(const UndulatorRep&);
virtual ~UndulatorRep();
/// Return clone.
// Return an identical deep copy of the element.
virtual ElementBase* clone() const;
/// Construct a read/write channel.
// This method constructs a Channel permitting read/write access to
// the attribute [b]aKey[/b] and returns it.
// If the attribute does not exist, it returns NULL.
virtual Channel* getChannel(const std::string& aKey, bool = false);
/// Get field.
// Version for non-constant object.
virtual NullField& getField();
/// Get field.
// Version for constant object.
virtual const NullField& getField() const;
/// Get geometry.
// Version for non-constant object.
virtual StraightGeometry& getGeometry();
/// Get geometry.
// Version for constant object.
virtual const StraightGeometry& getGeometry() const;
private:
// Not implemented.
void operator=(const UndulatorRep&);
/// The zero magnetic field.
NullField field;
/// The geometry.
StraightGeometry geometry;
};
#endif // CLASSIC_UndulatorRep_HH
......@@ -49,12 +49,6 @@ set (_SRCS
OpalStripper.cpp
)
include_directories (
${CMAKE_CURRENT_SOURCE_DIR}
)
add_opal_sources (${_SRCS})
set (HDRS
OpalBeamline.h
OpalBeamStripping.h
......@@ -105,4 +99,15 @@ set (HDRS
OpalOffset/OpalLocalCylindricalOffset.h
)
if (ENABLE_OPAL_FEL)
list (APPEND _SRCS OpalUndulator.cpp)
list (APPEND HDRS OpalUndulator.h)
endif ()
include_directories (
${CMAKE_CURRENT_SOURCE_DIR}
)
add_opal_sources (${_SRCS})
install (FILES ${HDRS} DESTINATION "${CMAKE_INSTALL_PREFIX}/include/Elements/OpalOffset")
//
// Class OpalUndulator
// Defines the Undulator/Wiggler element and its attributes.
//
// Copyright (c) 2020, Arnau Albà, Paul Scherrer Institut, Villigen PSI, Switzerland
// All rights reserved.
//
// Implemented as part of the MSc thesis
// "Start-to-End Modelling of the AWA Micro-Bunched Electron Cooling POP-Experiment"
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU Gen