Swarm-NG  1.1
tutorial_simple.cpp
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) 2009-2010 by Eric Ford & the Swarm-NG Development Team *
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU General Public License as published by *
6  * the Free Software Foundation; either version 3 of the License. *
7  * *
8  * This program is distributed in the hope that it will be useful, *
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
11  * GNU General Public License for more details. *
12  * *
13  * You should have received a copy of the GNU General Public License *
14  * along with this program; if not, write to the *
15  * Free Software Foundation, Inc., *
16  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17  ************************************************************************/
18 
25 /*
26  * This is a simple tutorial used in doxygen pages
27  * should go through program2doxygen before it
28  * can be used by doxygen.
29  *
30  *
31  */
32 // \page TutorialBeginner Beginner tutorial for using the API
33 //
34 // You can write your own scenarios for integrating ensembles and use parts
35 // and pieces of the Swarm-NG library for your C++ application.
36 //
37 // In this tutorial we go through a simple C++ program to show you how you can
38 // use Swarm-NG library. You can find the source file at src/tutorials/tutorial_simple.cpp
39 //
40 //
41 // We start at the first line of the program. You need to include needed headers to use the library.
42 //
43 // Some standard C++ libraries
44 #include <iostream>
45 // Include Swarm library headers. You may need to add other headers if you want to use
46 // More advanced feautures. But for simple ensemble creation and integration the following
47 // line should be enough
48 #include "swarm/swarm.h"
49 // We define a shortcut; because we need to use cudaThreadSynchronize() after
50 // every GPU call to make sure that we are in-sync with GPU.
51 #define SYNC cudaThreadSynchronize()
52 
53 // All the Swarm-NG classes are enclodes in swarm namespace, a C++ tradition. (std is the standard library)
54 using namespace swarm;
55 using namespace std;
56 
57 // We define parameters for integration as constants so we can change them later.
58 // We set the destination time for 5 revolutions. Each revolution is 2 * pi radians.
59 const double destination_time = 5 * 2 * M_PI ;
60 // Swarm uses the configuration data structure to pass most of parameters to creation functions
61 // Here we put all of our configuration items in a 2D string array.
62 const char * config_pairs[5][2] = {
63  { "integrator" , "hermite" }
64  ,{ "time_step", "0.001" }
65  ,{ "log_writer", "null" }
66  ,{ "nsys" , "4000" }
67  ,{ "nbod" , "3" }
68  };
69 
70 // The easy way to create a config object is from a 2D array containing pairs of strings.
71 // You can also use \ref swarm::config::load to load a configuration from a file.
72 // We use this config object to configure all parts of swarm. Note that not every function
73 // reads all the configuration items. For example, generate_ensemble only reads "nsys" and "nbod".
74 config cfg( config_pairs );
75 
76 // Since our program is short, we can put everything in the main function.
77 int main(int argc, char* argv[]){
78 
79  // First we create our reference ensemble. We use the automatic generation using generate_ensemble function
80  // This function creates a very stable ensemble of systems for us.
82 
83  // We have to make a copy of initial conditions. We would like to compare the results to initial conditions
84  // after integration
85  defaultEnsemble ens = ref.clone();
86 
87 
88  // Initialize Swarm library. Basically, it initializes CUDA system and default logging system.
89  swarm::init(cfg);
90 
91  // Select and create the integrator. While you can create an integrator by calling its constructor directly.
92  // It is recommended to use integrator::create since it gives you more flexibility at runtime.
93  // The create function looks in the swarm library and finds the integrator you requested from
94  // the list of available plugins.
95  Pintegrator integ = integrator::create(cfg);
96 
97  // Now we set-up the integrator for integrating.
98  //
99  // First set the ensemble. For a GPU integrator, the GPU memory will be allocated.
100  integ->set_ensemble(ens);
101  // Now set the destination time where we want to stop the integration.
102  integ->set_destination_time ( destination_time );
103  // Need to synchronize because \ref integrator::set_ensemble may upload data to GPU.
104  SYNC;
105 
106  // Now that everything is set-up, it is safe to pull the trigger and
107  // call the integrate method on integrator. Note that since we didn't set
108  // a logger for the integrator, it will use the default logging system.
109  integ->integrate();
110  // Need to synchronize because integrate is a GPU call.
111  SYNC;
112 
113  // Once the integration done, we need to examine the data. The easiest
114  // check is to see if the systems have preserved energy.
115  //
116  // find_max_energy_conservation_error is a utility function that compares
117  // two ensemble of systems. We compare our working ensemble ens to the
118  // unchanged ensemble ref.
119  double max_deltaE = find_max_energy_conservation_error(ens, ref );
120  std::cout << "Max Energy Conservation Error = " << max_deltaE << std::endl;
121 
122  // This concludes the program, at this point you will need to clean up the data and ensembles.
123  // But most of Swarm-NG objects are stored in reference-counter pointers and will be automatically
124  // deallocated by C++ runtime library.
125  return 0;
126 }
127 // If you want to do more with Swarm-NG, you may consider looking into
128 // following classes
129 // - \ref swarm::ensemble This is an abstarct class for ensembles, there are trivial methods to access the data
130 // in the ensemble. You can examine and change the ensemble the way you want.
131 // - \ref swarm::defaultEnsemble The concrete class which contains memory management for ensembles. Use \ref defaultEnsemble::create
132 // to create new ensembles. The arrays will be automatically allocated and de-allocated based on reference counting.
133 // - \ref swarm::snapshot::load_text Use this utility function to load an ensemble from a text file.
134 // - \ref swarm::snapshot::save_text Use this utility function to save an ensemble to a text file.
135 // - \ref swarm::log::manager Most users won't need it because the default log manager is used by all integrators.
136 // But if you need multiple log streams, you need to create your own log manager
137 // and use it in integrators by \ref integrator::set_log_manager method.
138 //
139 // To find the complete listing of this tutorial look at \ref src/tutorials/tutorial_simple.cpp in the source code repository.