diff --git a/src/amuse/community/secularmultiple/Makefile b/src/amuse/community/secularmultiple/Makefile index 6f6b633844..bcc8e2ea95 100644 --- a/src/amuse/community/secularmultiple/Makefile +++ b/src/amuse/community/secularmultiple/Makefile @@ -10,31 +10,46 @@ MPICC ?= mpicc CC = $(MPICC) CXX = $(MPICXX) - CXXFLAGS += -g -DTOOLBOX -O3 $(MUSE_INCLUDE_DIR) LDFLAGS+ = -lm $(MUSE_LD_FLAGS) -OBJS = interface.o src/types.o src/evolve.o src/structure.o src/ODE_system.o src/root_finding.o src/newtonian.o src/postnewtonian.o src/tides.o src/external.o src/cvode/cvode.o src/cvode/cvode_dense.o src/cvode/cvode_direct.o src/cvode/cvode_io.o src/cvode/nvector_serial.o src/cvode/sundials_dense.o src/cvode/sundials_direct.o src/cvode/sundials_math.o src/cvode/sundials_nvector.o +SRCDIR=src -all: worker_code +OBJS = $(SRCDIR)/interface.o $(SRCDIR)/src/types.o $(SRCDIR)/src/evolve.o \ +$(SRCDIR)/src/structure.o $(SRCDIR)/src/ODE_system.o \ +$(SRCDIR)/src/root_finding.o $(SRCDIR)/src/newtonian.o \ +$(SRCDIR)/src/postnewtonian.o $(SRCDIR)/src/tides.o \ +$(SRCDIR)/src/external.o $(SRCDIR)/src/VRR.o $(SRCDIR)/src/cvode/cvode.o \ +$(SRCDIR)/src/cvode/cvode_dense.o $(SRCDIR)/src/cvode/cvode_direct.o \ +$(SRCDIR)/src/cvode/cvode_io.o $(SRCDIR)/src/cvode/nvector_serial.o \ +$(SRCDIR)/src/cvode/sundials_dense.o $(SRCDIR)/src/cvode/sundials_direct.o \ +$(SRCDIR)/src/cvode/sundials_math.o $(SRCDIR)/src/cvode/sundials_nvector.o -cleanall: clean - $(RM) worker_code * +all: secularmultiple_worker clean: - rm -f *.so *.o *.pyc worker_code.cc src/*.o* + rm -f *.so *.o *.pyc worker_code.cc $(SRCDIR)/*.o* $(SRCDIR)/src/*.o* -distclean: - rm -f *.so *.o *.pyc worker_code.cc src/*.o* src/cvode/*.o* - -worker_code.cc: interface.py +distclean: clean + rm -rf src + +worker_code.cc: worker_code.h interface.py $(CODE_GENERATOR) --type=c interface.py SecularMultipleInterface -o $@ -worker_code: worker_code.cc $(OBJS) - $(MPICXX) $(CXXFLAGS) $@.cc $(OBJS) -o $@ +worker_code.h: interface.py + $(CODE_GENERATOR) --type=h interface.py SecularMultipleInterface -o $@ + +secularmultiple_worker: worker_code.cc $(OBJS) + $(MPICXX) $(CXXFLAGS) worker_code.cc $(OBJS) -o $@ .cc.o: $< $(CXX) $(CXXFLAGS) -c -o $@ $< .c.o: $< $(CC) $(CXXFLAGS) -c -o $@ $< + +src/interface.cpp: + make -C . download + +download: + git clone -b master https://github.com/hamers/secularmultiple.git src diff --git a/src/amuse/community/secularmultiple/interface.cpp b/src/amuse/community/secularmultiple/interface.cpp deleted file mode 100644 index 1410a4bb55..0000000000 --- a/src/amuse/community/secularmultiple/interface.cpp +++ /dev/null @@ -1,2101 +0,0 @@ -#include "src/types.h" -#include "interface.h" -#include "src/evolve.h" - - -int highest_particle_index = 0; -int highest_external_particle_index = 0; -ParticlesMap particlesMap; -External_ParticlesMap external_particlesMap; - -double relative_tolerance = 1.0e-16; -double absolute_tolerance_eccentricity_vectors = 1.0e-14; -bool include_quadrupole_order_terms = true; -bool include_octupole_order_binary_pair_terms = true; -bool include_octupole_order_binary_triplet_terms = false; -bool include_hexadecupole_order_binary_pair_terms = false; -bool include_dotriacontupole_order_binary_pair_terms = false; -int orbital_phases_random_seed = 0; - -/******************* -/* basic interface * - ******************/ - -int new_particle(int * index_of_the_particle, bool is_binary) -{ - - *index_of_the_particle = highest_particle_index; - Particle * p = new Particle(highest_particle_index, is_binary); - particlesMap[highest_particle_index] = p; - - highest_particle_index++; - - return 0; -} -int delete_particle(int index_of_the_particle) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - particlesMap.erase(index_of_the_particle); - - return 0; -} - -int set_children(int index_of_the_particle, int child1, int child2) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->child1 = child1; - p->child2 = child2; - - return 0; -} -int get_children(int index_of_the_particle, int *child1, int *child2) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *child1 = p->child1; - *child2 = p->child2; - - return 0; -} - -int set_mass(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->mass = value; - - return 0; -} -int get_mass(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->mass; - - return 0; -} - -int set_mass_dot_external(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->mass_dot_external = value; - - return 0; -} -int get_mass_dot_external(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->mass_dot_external; - - return 0; -} - -int set_radius(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->radius = value; - - return 0; -} -int get_radius(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->radius; - - return 0; -} - -int set_radius_dot_external(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->radius_dot_external = value; - - return 0; -} -int get_radius_dot_external(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->radius_dot_external; - - return 0; -} - -int set_radius_ddot_external(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->radius_ddot_external = value; - - return 0; -} -int get_radius_ddot_external(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->radius_ddot_external; - - return 0; -} - -int get_level(int index_of_the_particle, int *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->level; - - return 0; -} - -int set_stellar_type(int index_of_the_particle, int value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->stellar_type = value; - - return 0; -} -int get_stellar_type(int index_of_the_particle, int *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->stellar_type; - - return 0; -} - -int set_true_anomaly(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->true_anomaly = value; - - return 0; -} -int get_true_anomaly(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->true_anomaly; - - return 0; -} -int set_sample_orbital_phases_randomly(int index_of_the_particle, bool value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->sample_orbital_phases_randomly = value; - - return 0; -} -int get_sample_orbital_phases_randomly(int index_of_the_particle, bool *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->sample_orbital_phases_randomly; - - return 0; -} - - -/******************************* - * instantaneous perturbations * - * ****************************/ - -int set_instantaneous_perturbation_delta_mass(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->instantaneous_perturbation_delta_mass = value; - - return 0; -} -int get_instantaneous_perturbation_delta_mass(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->instantaneous_perturbation_delta_mass; - - return 0; -} - -int set_instantaneous_perturbation_delta_position(int index_of_the_particle, double x, double y, double z) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->instantaneous_perturbation_delta_position_x = x; - p->instantaneous_perturbation_delta_position_y = y; - p->instantaneous_perturbation_delta_position_z = z; - - return 0; -} -int get_instantaneous_perturbation_delta_position(int index_of_the_particle, double *x, double *y, double *z) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *x = p->instantaneous_perturbation_delta_position_x; - *y = p->instantaneous_perturbation_delta_position_y; - *z = p->instantaneous_perturbation_delta_position_z; - - return 0; -} - -int set_instantaneous_perturbation_delta_velocity(int index_of_the_particle, double x, double y, double z) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->instantaneous_perturbation_delta_velocity_x = x; - p->instantaneous_perturbation_delta_velocity_y = y; - p->instantaneous_perturbation_delta_velocity_z = z; - - return 0; -} -int get_instantaneous_perturbation_delta_velocity(int index_of_the_particle, double *x, double *y, double *z) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *x = p->instantaneous_perturbation_delta_velocity_x; - *y = p->instantaneous_perturbation_delta_velocity_y; - *z = p->instantaneous_perturbation_delta_velocity_z; - - return 0; -} - - -/************ - * external * - * *********/ - -int new_external_particle(int *index_of_the_external_particle, double mass) -{ - - *index_of_the_external_particle = highest_external_particle_index; - External_Particle *f = new External_Particle(highest_external_particle_index); - external_particlesMap[highest_external_particle_index] = f; - - highest_external_particle_index++; - f->mass = mass; - - return 0; -} -int delete_external_particle(int index_of_the_external_particle) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - external_particlesMap.erase(index_of_the_external_particle); - - return 0; -} - -int set_external_mass(int index_of_the_external_particle, double value) -{ - //printf("set_external_mass\n"); - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - f->mass = value; - - return 0; -} -int get_external_mass(int index_of_the_external_particle, double *value) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - *value = f->mass; - - return 0; -} - -int set_external_path(int index_of_the_external_particle, int value) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - f->path = value; - - return 0; -} -int get_external_path(int index_of_the_external_particle, int *value) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - *value = f->path; - - return 0; -} - -int set_external_mode(int index_of_the_external_particle, int value) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - f->mode = value; - - return 0; -} -int get_external_mode(int index_of_the_external_particle, int *value) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - *value = f->mode; - - return 0; -} - -int set_external_t_ref(int index_of_the_external_particle, double value) -{ - //printf("set_external_t_ref\n"); - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - f->t_ref = value; - - return 0; -} -int get_external_t_ref(int index_of_the_external_particle, double *value) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - *value = f->t_ref; - - return 0; -} - -int set_external_t_passed(int index_of_the_external_particle, double value) -{ - //printf("set_external_t_ref\n"); - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - f->t_passed = value; - - return 0; -} -int get_external_t_passed(int index_of_the_external_particle, double *value) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - *value = f->t_passed; - - return 0; -} - -int set_external_r0_vectors(int index_of_the_external_particle, double vec_x, double vec_y, double vec_z) -{ - //printf("set_external_r0_vectors\n"); - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - f->r0_vec_x = vec_x; - f->r0_vec_y = vec_y; - f->r0_vec_z = vec_z; - - return 0; -} -int get_external_r0_vectors(int index_of_the_external_particle, double *vec_x, double *vec_y, double *vec_z) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - *vec_x = f->r0_vec_x; - *vec_y = f->r0_vec_y; - *vec_z = f->r0_vec_z; - - return 0; -} - -int set_external_rdot_vectors(int index_of_the_external_particle, double rdot_vec_x, double rdot_vec_y, double rdot_vec_z) -{ - //printf("set_external_rdot_vectors\n"); - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - f->rdot_vec_x = rdot_vec_x; - f->rdot_vec_y = rdot_vec_y; - f->rdot_vec_z = rdot_vec_z; - - return 0; -} -int get_external_rdot_vectors(int index_of_the_external_particle, double *rdot_vec_x, double *rdot_vec_y, double *rdot_vec_z) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - *rdot_vec_x = f->rdot_vec_x; - *rdot_vec_y = f->rdot_vec_y; - *rdot_vec_z = f->rdot_vec_z; - - return 0; -} - - -int set_external_periapse_distance(int index_of_the_external_particle, double value) -{ - //printf("set_external_t_ref\n"); - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - f->periapse_distance = value; - - return 0; -} -int get_external_periapse_distance(int index_of_the_external_particle, double *value) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - *value = f->periapse_distance; - - return 0; -} - -int set_external_eccentricity(int index_of_the_external_particle, double value) -{ - //printf("set_external_t_ref\n"); - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - f->eccentricity = value; - - return 0; -} -int get_external_eccentricity(int index_of_the_external_particle, double *value) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - *value = f->eccentricity; - - return 0; -} - -int set_external_e_hat_vectors(int index_of_the_external_particle, double x, double y, double z) -{ - //printf("set_external_rdot_vectors\n"); - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - f->e_hat_vec_x = x; - f->e_hat_vec_y = y; - f->e_hat_vec_z = z; - - return 0; -} -int get_external_e_hat_vectors(int index_of_the_external_particle, double *x, double *y, double *z) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - *x = f->e_hat_vec_x; - *y = f->e_hat_vec_y; - *z = f->e_hat_vec_z; - - return 0; -} - -int set_external_h_hat_vectors(int index_of_the_external_particle, double x, double y, double z) -{ - //printf("set_external_rdot_vectors\n"); - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - f->h_hat_vec_x = x; - f->h_hat_vec_y = y; - f->h_hat_vec_z = z; - - return 0; -} -int get_external_h_hat_vectors(int index_of_the_external_particle, double *x, double *y, double *z) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - *x = f->h_hat_vec_x; - *y = f->h_hat_vec_y; - *z = f->h_hat_vec_z; - - return 0; -} - - -int get_external_r_vectors(int index_of_the_external_particle, double *r_vec_x, double *r_vec_y, double *r_vec_z) -{ - if (index_of_the_external_particle > highest_external_particle_index) - { - return -1; - } - - External_Particle *f = external_particlesMap[index_of_the_external_particle]; - *r_vec_x = f->r_vec_x; - *r_vec_y = f->r_vec_y; - *r_vec_z = f->r_vec_z; - - return 0; -} - - - - - - - -/**************** -/* spin vectors * - ****************/ - -int set_spin_vector(int index_of_the_particle, double spin_vec_x, double spin_vec_y, double spin_vec_z) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->spin_vec_x = spin_vec_x; - p->spin_vec_y = spin_vec_y; - p->spin_vec_z = spin_vec_z; - - return 0; -} -int get_spin_vector(int index_of_the_particle, double *spin_vec_x, double *spin_vec_y, double *spin_vec_z) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *spin_vec_x = p->spin_vec_x; - *spin_vec_y = p->spin_vec_y; - *spin_vec_z = p->spin_vec_z; - - return 0; -} - -int set_spin_vector_dot_external(int index_of_the_particle, double spin_vec_x_dot_external, double spin_vec_y_dot_external, double spin_vec_z_dot_external) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->spin_vec_x_dot_external = spin_vec_x_dot_external; - p->spin_vec_y_dot_external = spin_vec_y_dot_external; - p->spin_vec_z_dot_external = spin_vec_z_dot_external; - - return 0; -} -int get_spin_vector_dot_external(int index_of_the_particle, double *spin_vec_x_dot_external, double *spin_vec_y_dot_external, double *spin_vec_z_dot_external) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *spin_vec_x_dot_external = p->spin_vec_x_dot_external; - *spin_vec_y_dot_external = p->spin_vec_y_dot_external; - *spin_vec_z_dot_external = p->spin_vec_z_dot_external; - - return 0; -} - -/**************************** -/* orbital vectors/elements * - ****************************/ - -int set_orbital_vectors(int index_of_the_particle, double e_vec_x, double e_vec_y, double e_vec_z, \ - double h_vec_x, double h_vec_y, double h_vec_z) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->e_vec_x = e_vec_x; - p->e_vec_y = e_vec_y; - p->e_vec_z = e_vec_z; - p->h_vec_x = h_vec_x; - p->h_vec_y = h_vec_y; - p->h_vec_z = h_vec_z; - - return 0; -} -int get_orbital_vectors(int index_of_the_particle, double *e_vec_x, double *e_vec_y, double *e_vec_z, \ - double *h_vec_x, double *h_vec_y, double *h_vec_z) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *e_vec_x = p->e_vec_x; - *e_vec_y = p->e_vec_y; - *e_vec_z = p->e_vec_z; - *h_vec_x = p->h_vec_x; - *h_vec_y = p->h_vec_y; - *h_vec_z = p->h_vec_z; - - return 0; -} - -int set_orbital_vectors_dot_external(int index_of_the_particle, double e_vec_x_dot_external, double e_vec_y_dot_external, double e_vec_z_dot_external, \ - double h_vec_x_dot_external, double h_vec_y_dot_external, double h_vec_z_dot_external) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->e_vec_x_dot_external = e_vec_x_dot_external; - p->e_vec_y_dot_external = e_vec_y_dot_external; - p->e_vec_z_dot_external = e_vec_z_dot_external; - p->h_vec_x_dot_external = h_vec_x_dot_external; - p->h_vec_y_dot_external = h_vec_y_dot_external; - p->h_vec_z_dot_external = h_vec_z_dot_external; - - return 0; -} -int get_orbital_vectors_dot_external(int index_of_the_particle, double *e_vec_x_dot_external, double *e_vec_y_dot_external, double *e_vec_z_dot_external, \ - double *h_vec_x_dot_external, double *h_vec_y_dot_external, double *h_vec_z_dot_external) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *e_vec_x_dot_external = p->e_vec_x_dot_external; - *e_vec_y_dot_external = p->e_vec_y_dot_external; - *e_vec_z_dot_external = p->e_vec_z_dot_external; - *h_vec_x_dot_external = p->h_vec_x_dot_external; - *h_vec_y_dot_external = p->h_vec_y_dot_external; - *h_vec_z_dot_external = p->h_vec_z_dot_external; - - return 0; -} - -int set_orbital_elements(int index_of_the_particle, double semimajor_axis, double eccentricity, \ - double inclination, double argument_of_pericenter, double longitude_of_ascending_node) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - if (p->is_binary == false) - { - return 0; - } - - /* determine masses in all binaries */ - int N_bodies, N_binaries, N_root_finding; - determine_binary_parents_and_levels(&particlesMap, &N_bodies, &N_binaries, &N_root_finding); - set_binary_masses_from_body_masses(&particlesMap); - - compute_orbital_vectors_from_orbital_elements(p->child1_mass, p->child2_mass, semimajor_axis, eccentricity, \ - inclination, argument_of_pericenter, longitude_of_ascending_node, \ - &(p->e_vec_x), &(p->e_vec_y), &(p->e_vec_z), &(p->h_vec_x), &(p->h_vec_y), &(p->h_vec_z) ); - - return 0; -} -int get_orbital_elements(int index_of_the_particle, double *semimajor_axis, double *eccentricity, \ - double *inclination, double *argument_of_pericenter, double *longitude_of_ascending_node) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - if (p->is_binary == false) - { - return 0; - } - - double h_tot_vec[3]; - compute_h_tot_vector(&particlesMap,h_tot_vec); - - /* determine masses in all binaries */ - int N_bodies, N_binaries, N_root_finding; - determine_binary_parents_and_levels(&particlesMap, &N_bodies, &N_binaries, &N_root_finding); - set_binary_masses_from_body_masses(&particlesMap); - - compute_orbital_elements_from_orbital_vectors(p->child1_mass, p->child2_mass, h_tot_vec, \ - p->e_vec_x,p->e_vec_y,p->e_vec_z,p->h_vec_x,p->h_vec_y,p->h_vec_z, - semimajor_axis, eccentricity, inclination, argument_of_pericenter, longitude_of_ascending_node); - return 0; -} - - - -int set_position_vector(int index_of_the_particle, double x, double y, double z) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->position_x = x; - p->position_y = y; - p->position_z = z; - - return 0; -} -int get_position_vector(int index_of_the_particle, double *x, double *y, double *z) -{ - //printf("get_position_vector\n"); - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - set_positions_and_velocities(&particlesMap); - - Particle * p = particlesMap[index_of_the_particle]; - *x = p->position_x; - *y = p->position_y; - *z = p->position_z; - - return 0; -} - -int set_velocity_vector(int index_of_the_particle, double x, double y, double z) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->velocity_x = x; - p->velocity_y = y; - p->velocity_z = z; - - return 0; -} -int get_velocity_vector(int index_of_the_particle, double *x, double *y, double *z) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - set_positions_and_velocities(&particlesMap); - - Particle * p = particlesMap[index_of_the_particle]; - *x = p->velocity_x; - *y = p->velocity_y; - *z = p->velocity_z; - - return 0; -} - -/************ -/* PN terms * - ************/ - -int set_include_pairwise_1PN_terms(int index_of_the_particle, bool include_pairwise_1PN_terms) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->include_pairwise_1PN_terms = include_pairwise_1PN_terms; - - return 0; -} -int get_include_pairwise_1PN_terms(int index_of_the_particle, bool *include_pairwise_1PN_terms) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *include_pairwise_1PN_terms = p->include_pairwise_1PN_terms; - - return 0; -} - -int set_include_pairwise_25PN_terms(int index_of_the_particle, bool include_pairwise_25PN_terms) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->include_pairwise_25PN_terms = include_pairwise_25PN_terms; - - return 0; -} -int get_include_pairwise_25PN_terms(int index_of_the_particle, bool *include_pairwise_25PN_terms) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *include_pairwise_25PN_terms = p->include_pairwise_25PN_terms; - - return 0; -} - - -/********* -/* tides * - *********/ -int set_include_tidal_friction_terms(int index_of_the_particle, bool include_tidal_friction_terms) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->include_tidal_friction_terms = include_tidal_friction_terms; - - return 0; -} -int get_include_tidal_friction_terms(int index_of_the_particle, bool *include_tidal_friction_terms) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *include_tidal_friction_terms = p->include_tidal_friction_terms; - - return 0; -} - -int set_tides_method(int index_of_the_particle, int tides_method) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->tides_method = tides_method; - - return 0; -} -int get_tides_method(int index_of_the_particle, int *tides_method) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *tides_method = p->tides_method; - - return 0; -} - -int set_include_tidal_bulges_precession_terms(int index_of_the_particle, bool include_tidal_bulges_precession_terms) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->include_tidal_bulges_precession_terms = include_tidal_bulges_precession_terms; - - return 0; -} -int get_include_tidal_bulges_precession_terms(int index_of_the_particle, bool *include_tidal_bulges_precession_terms) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *include_tidal_bulges_precession_terms = p->include_tidal_bulges_precession_terms; - - return 0; -} - -int set_include_rotation_precession_terms(int index_of_the_particle, bool include_rotation_precession_terms) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->include_rotation_precession_terms = include_rotation_precession_terms; - - return 0; -} - -int get_include_rotation_precession_terms(int index_of_the_particle, bool *include_rotation_precession_terms) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *include_rotation_precession_terms = p->include_rotation_precession_terms; - - return 0; -} - -int set_minimum_eccentricity_for_tidal_precession(int index_of_the_particle, double minimum_eccentricity_for_tidal_precession) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->minimum_eccentricity_for_tidal_precession = minimum_eccentricity_for_tidal_precession; - - return 0; -} -int get_minimum_eccentricity_for_tidal_precession(int index_of_the_particle, double *minimum_eccentricity_for_tidal_precession) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *minimum_eccentricity_for_tidal_precession = p->minimum_eccentricity_for_tidal_precession; - - return 0; -} - -int set_tides_apsidal_motion_constant(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->tides_apsidal_motion_constant = value; - - return 0; -} -int get_tides_apsidal_motion_constant(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *value = p->tides_apsidal_motion_constant; - - return 0; -} - -int set_tides_gyration_radius(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->tides_gyration_radius = value; - - return 0; -} -int get_tides_gyration_radius(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *value = p->tides_gyration_radius; - - return 0; -} - -int set_tides_viscous_time_scale(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->tides_viscous_time_scale = value; - - return 0; -} -int get_tides_viscous_time_scale(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *value = p->tides_viscous_time_scale; - - return 0; -} - -int set_tides_viscous_time_scale_prescription(int index_of_the_particle, int value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->tides_viscous_time_scale_prescription = value; - - return 0; -} -int get_tides_viscous_time_scale_prescription(int index_of_the_particle, int *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *value = p->tides_viscous_time_scale_prescription; - - return 0; -} - -int set_convective_envelope_mass(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->convective_envelope_mass = value; - - return 0; -} -int get_convective_envelope_mass(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *value = p->convective_envelope_mass; - - return 0; -} - -int set_convective_envelope_radius(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->convective_envelope_radius = value; - - return 0; -} -int get_convective_envelope_radius(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *value = p->convective_envelope_radius; - - return 0; -} - -int set_luminosity(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->luminosity = value; - - return 0; -} -int get_luminosity(int index_of_the_particle, double *value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *value = p->luminosity; - - return 0; -} - -/**************** -/* root finding * - ****************/ - -/* secular breakdown*/ -int set_check_for_secular_breakdown(int index_of_the_particle, bool value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->check_for_secular_breakdown = value; - - return 0; -} -int get_check_for_secular_breakdown(int index_of_the_particle, bool* value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->check_for_secular_breakdown; - - return 0; -} - -/* dynamical instablity*/ -int set_check_for_dynamical_instability(int index_of_the_particle, bool value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->check_for_dynamical_instability = value; - - return 0; -} -int get_check_for_dynamical_instability(int index_of_the_particle, bool* value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->check_for_dynamical_instability; - - return 0; -} - -int set_dynamical_instability_criterion(int index_of_the_particle, int value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->dynamical_instability_criterion = value; - - return 0; -} -int get_dynamical_instability_criterion(int index_of_the_particle, int* value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->dynamical_instability_criterion; - - return 0; -} - - -int set_dynamical_instability_central_particle(int index_of_the_particle, int value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->dynamical_instability_central_particle = value; - - return 0; -} -int get_dynamical_instability_central_particle(int index_of_the_particle, int* value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->dynamical_instability_central_particle; - - return 0; -} - -int set_dynamical_instability_K_parameter(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->dynamical_instability_K_parameter = value; - - return 0; -} -int get_dynamical_instability_K_parameter(int index_of_the_particle, double* value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->dynamical_instability_K_parameter; - - return 0; -} - -/* physical collision / orbit crossing*/ -int set_check_for_physical_collision_or_orbit_crossing(int index_of_the_particle, bool value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->check_for_physical_collision_or_orbit_crossing = value; - - return 0; -} -int get_check_for_physical_collision_or_orbit_crossing(int index_of_the_particle, bool* value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->check_for_physical_collision_or_orbit_crossing; - - return 0; -} - -/* minimum periapse distance reached */ -int set_check_for_minimum_periapse_distance(int index_of_the_particle, bool value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->check_for_minimum_periapse_distance = value; - - return 0; -} -int get_check_for_minimum_periapse_distance(int index_of_the_particle, bool* value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->check_for_minimum_periapse_distance; - - return 0; -} -int set_check_for_minimum_periapse_distance_value(int index_of_the_particle, double value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->check_for_minimum_periapse_distance_value = value; - - return 0; -} -int get_check_for_minimum_periapse_distance_value(int index_of_the_particle, double* value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->check_for_minimum_periapse_distance_value; - - return 0; -} - -/* RLOF at pericentre */ -int set_check_for_RLOF_at_pericentre(int index_of_the_particle, bool value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->check_for_RLOF_at_pericentre = value; - - return 0; -} -int get_check_for_RLOF_at_pericentre(int index_of_the_particle, bool* value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->check_for_RLOF_at_pericentre; - - return 0; -} - -int set_check_for_RLOF_at_pericentre_use_sepinsky_fit(int index_of_the_particle, bool value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - p->check_for_RLOF_at_pericentre_use_sepinsky_fit = value; - - return 0; -} -int get_check_for_RLOF_at_pericentre_use_sepinsky_fit(int index_of_the_particle, bool* value) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - *value = p->check_for_RLOF_at_pericentre_use_sepinsky_fit; - - return 0; -} - - -/* retrieve root finding state */ -int set_root_finding_state(int index_of_the_particle, bool secular_breakdown_has_occurred, bool dynamical_instability_has_occurred, bool physical_collision_or_orbit_crossing_has_occurred, bool minimum_periapse_distance_has_occurred, bool RLOF_at_pericentre_has_occurred) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - p->secular_breakdown_has_occurred = secular_breakdown_has_occurred; - p->dynamical_instability_has_occurred = dynamical_instability_has_occurred; - p->physical_collision_or_orbit_crossing_has_occurred = physical_collision_or_orbit_crossing_has_occurred; - p->minimum_periapse_distance_has_occurred = minimum_periapse_distance_has_occurred; - p->RLOF_at_pericentre_has_occurred = RLOF_at_pericentre_has_occurred; - - return 0; -} -int get_root_finding_state(int index_of_the_particle, bool *secular_breakdown_has_occurred, bool *dynamical_instability_has_occurred, bool *physical_collision_or_orbit_crossing_has_occurred, bool* minimum_periapse_distance_has_occurred, bool *RLOF_at_pericentre_has_occurred) -{ - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - - *secular_breakdown_has_occurred = p->secular_breakdown_has_occurred; - *dynamical_instability_has_occurred = p->dynamical_instability_has_occurred; - *physical_collision_or_orbit_crossing_has_occurred = p->physical_collision_or_orbit_crossing_has_occurred; - *minimum_periapse_distance_has_occurred = p->minimum_periapse_distance_has_occurred; - *RLOF_at_pericentre_has_occurred = p->RLOF_at_pericentre_has_occurred; - - return 0; -} - - -/******************** -/* evolve interface * - ********************/ - -int evolve_interface(double start_time, double time_step, double *output_time, double *hamiltonian, int *flag, int *error_code) -{ - int result = evolve(&particlesMap, &external_particlesMap, start_time, time_step, output_time, hamiltonian, flag, error_code); - - return result; -} - -/* set levels and masses */ -int determine_binary_parents_levels_and_masses_interface() -{ - //printf("determine_binary_parents_levels_and_masses_interface\n"); - int N_bodies, N_binaries, N_root_finding; - determine_binary_parents_and_levels(&particlesMap, &N_bodies, &N_binaries, &N_root_finding); - set_binary_masses_from_body_masses(&particlesMap); - - return 0; -} - -int apply_external_perturbation_assuming_integrated_orbits_interface() -{ - //printf("apply_external_perturbation_assuming_integrated_orbits_interface\n"); - apply_external_perturbation_assuming_integrated_orbits(&particlesMap, &external_particlesMap); - - return 0; -} - -int apply_user_specified_instantaneous_perturbation_interface() -{ - //printf("apply_user_specified_instantaneous_perturbation\n"); - apply_user_specified_instantaneous_perturbation(&particlesMap); - - return 0; -} - -int set_positions_and_velocities_interface() -{ - set_positions_and_velocities(&particlesMap); -} - -/********************************************** -/* orbital element/vector conversion routines * - **********************************************/ -void compute_h_tot_vector(ParticlesMap* particlesMap, double h_tot_vec[3]) -{ - for (int i=0; i<3; i++) - { - h_tot_vec[i] = 0.0; - } - - ParticlesMapIterator it_p; - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *p = (*it_p).second; - if (p->is_binary == 1) - { - h_tot_vec[0] += p->h_vec_x; - h_tot_vec[1] += p->h_vec_y; - h_tot_vec[2] += p->h_vec_z; - } - } -// printf("compute_h_tot_vector %g %g %g\n",h_tot_vec[0],h_tot_vec[1],h_tot_vec[2]); -} - -int compute_orbital_vectors_from_orbital_elements(double child1_mass, double child2_mass, double semimajor_axis, double eccentricity, double inclination, double argument_of_pericenter,double longitude_of_ascending_node, double *e_vec_x, double *e_vec_y, double *e_vec_z, double *h_vec_x, double *h_vec_y, double *h_vec_z) -{ - double cos_INCL = cos(inclination); - double sin_INCL = sin(inclination); - double cos_AP = cos(argument_of_pericenter); - double sin_AP = sin(argument_of_pericenter); - double cos_LAN = cos(longitude_of_ascending_node); - double sin_LAN = sin(longitude_of_ascending_node); - - double h = (child1_mass*child2_mass*sqrt(CONST_G*semimajor_axis/(child1_mass+child2_mass)))*sqrt(1.0 - eccentricity*eccentricity); - - *e_vec_x = eccentricity*(cos_LAN*cos_AP - sin_LAN*sin_AP*cos_INCL); - *e_vec_y = eccentricity*(sin_LAN*cos_AP + cos_LAN*sin_AP*cos_INCL); - *e_vec_z = eccentricity*(sin_AP*sin_INCL); - - *h_vec_x = h*sin_LAN*sin_INCL; - *h_vec_y = -h*cos_LAN*sin_INCL; - *h_vec_z = h*cos_INCL; - - return 0; -} - -int compute_orbital_elements_from_orbital_vectors(double child1_mass, double child2_mass, double h_tot_vec[3], double e_vec_x, double e_vec_y, double e_vec_z, double h_vec_x, double h_vec_y, double h_vec_z, double *semimajor_axis, double *eccentricity, double *inclination, double *argument_of_pericenter,double *longitude_of_ascending_node) -{ - double e_vec[3] = {e_vec_x,e_vec_y,e_vec_z}; - double h_vec[3] = {h_vec_x,h_vec_y,h_vec_z}; - double eccentricity_squared = norm3_squared(e_vec); - *eccentricity = sqrt(eccentricity_squared); - double h_squared = norm3_squared(h_vec); - *semimajor_axis = h_squared*(child1_mass+child2_mass)/( CONST_G*child1_mass*child1_mass*child2_mass*child2_mass*(1.0 - eccentricity_squared) ); - double h = sqrt(h_squared); - -// double x_vec[3] = {1.0,0.0,0.0}; -// double y_vec[3] = {0.0,1.0,0.0}; -// double z_vec[3] = {0.0,0.0,1.0}; - - double h_tot = norm3(h_tot_vec); -// printf("h_tot %g x %g y %g z %g\n",h_tot,h_tot_vec[0],h_tot_vec[1],h_tot_vec[2]); - double x_vec[3], y_vec[3], z_vec[3]; - for (int i=0; i<3; i++) - { - z_vec[i] = h_tot_vec[i]/h_tot; - } - -// printf("test %g %g %g\n",z_vec[0],z_vec[1],z_vec[2]); - z_vec[0] = 0.0; - z_vec[1] = 0.0; - z_vec[2] = 1.0; - - /* the above assumes that the total angular momentum vector does not change (i.e. no SNe effects etc.) */ - - double f = 1.0/sqrt( z_vec[0]*z_vec[0] + z_vec[2]*z_vec[2] ); - x_vec[0] = z_vec[2]*f; - x_vec[1] = 0.0; - x_vec[2] = -z_vec[0]*f; - cross3(z_vec,x_vec,y_vec); - - double cos_INCL = dot3(h_vec,z_vec)/h; - - double LAN_vec[3],LAN_vec_unit[3]; - cross3(z_vec,h_vec,LAN_vec); - double LAN_vec_norm = norm3(LAN_vec); - - double e_vec_unit[3],h_vec_unit[3]; - - for (int i=0; i<3; i++) - { - LAN_vec_unit[i] = LAN_vec[i]/LAN_vec_norm; - e_vec_unit[i] = e_vec[i]/(*eccentricity); - h_vec_unit[i] = h_vec[i]/h; - } - - double sin_LAN = dot3(LAN_vec_unit,y_vec); - double cos_LAN = dot3(LAN_vec_unit,x_vec); - - double e_vec_unit_cross_h_vec_unit[3]; - cross3(e_vec_unit,h_vec_unit,e_vec_unit_cross_h_vec_unit); - double sin_AP = dot3(LAN_vec_unit,e_vec_unit_cross_h_vec_unit); - double cos_AP = dot3(LAN_vec_unit,e_vec_unit); - - *inclination = acos(cos_INCL); - *argument_of_pericenter = atan2(sin_AP,cos_AP); - *longitude_of_ascending_node = atan2(sin_LAN,cos_LAN); - - return 0; -} - -int get_inclination_relative_to_parent(int index_of_the_particle, double *inclination_relative_to_parent) -{ - - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - if (p->is_binary == 0) - { - *inclination_relative_to_parent = 0.0; - return 0; - } - if (p->parent == -1) - { - *inclination_relative_to_parent = 0.0; - return 0; - } - - Particle *parent = particlesMap[p->parent]; - - - double h1_vec[3] = {p->h_vec_x,p->h_vec_y,p->h_vec_z}; - double h2_vec[3] = {parent->h_vec_x,parent->h_vec_y,parent->h_vec_z}; - - double h1 = norm3(h1_vec); - double h2 = norm3(h2_vec); - - *inclination_relative_to_parent = acos( dot3(h1_vec,h2_vec)/(h1*h2) ); - - return 0; -} - - -void compute_eccentric_anomaly_from_mean_anomaly(double mean_anomaly, double eccentricity, double *cos_eccentric_anomaly, double *sin_eccentric_anomaly) -{ - double eccentric_anomaly; - double eccentric_anomaly_next = mean_anomaly; - double epsilon = 1e-10; - double error = 2.0*epsilon; - int j = 0; - while (error > epsilon || j < 15) - { - j += 1; - eccentric_anomaly = eccentric_anomaly_next; - eccentric_anomaly_next = eccentric_anomaly - (eccentric_anomaly - eccentricity*sin(eccentric_anomaly) - mean_anomaly)/(1.0 - eccentricity*cos(eccentric_anomaly)); - error = fabs(eccentric_anomaly_next - eccentric_anomaly); - } - *cos_eccentric_anomaly = cos(eccentric_anomaly); - *sin_eccentric_anomaly = sin(eccentric_anomaly); -} - -void compute_true_anomaly_from_eccentric_anomaly(double cos_eccentric_anomaly, double sin_eccentric_anomaly, double eccentricity, double *cos_true_anomaly, double *sin_true_anomaly) -{ - *cos_true_anomaly = (cos_eccentric_anomaly - eccentricity)/(1.0 - eccentricity*cos_eccentric_anomaly); - *sin_true_anomaly = sqrt(1.0 - eccentricity*eccentricity)*sin_eccentric_anomaly/(1.0 - eccentricity*cos_eccentric_anomaly); -} - -double compute_true_anomaly_from_mean_anomaly(double mean_anomaly, double eccentricity) -{ - double cos_eccentric_anomaly,sin_eccentric_anomaly; - double cos_true_anomaly,sin_true_anomaly; - - compute_eccentric_anomaly_from_mean_anomaly(mean_anomaly,eccentricity,&cos_eccentric_anomaly,&sin_eccentric_anomaly); - compute_true_anomaly_from_eccentric_anomaly(cos_eccentric_anomaly,sin_eccentric_anomaly,eccentricity,&cos_true_anomaly,&sin_true_anomaly); - double true_anomaly = atan2(sin_true_anomaly,cos_true_anomaly); - - return true_anomaly; -} - -double sample_random_true_anomaly(double eccentricity,int seed) -{ - srand(seed); - double x = ((double) rand() / (RAND_MAX)); - double mean_anomaly = (2.0*x - 1.0)*M_PI; - double true_anomaly = compute_true_anomaly_from_mean_anomaly(mean_anomaly,eccentricity); - - return true_anomaly; -} - -void from_orbital_vectors_to_cartesian(double child1_mass, double child2_mass, double e_vec[3], double h_vec[3], double true_anomaly, double r[3], double v[3]) -{ - double total_mass = child1_mass + child2_mass; - - double e = norm3(e_vec); - double h = norm3(h_vec); - - double e_vec_unit[3],q_vec_unit[3],q_vec[3]; - cross3(h_vec,e_vec,q_vec); - double q = norm3(q_vec); - - int i; - for (i=0; i<3; i++) - { - e_vec_unit[i] = e_vec[i]/e; - q_vec_unit[i] = q_vec[i]/q; - } - - double e_p2 = e*e; - double j_p2 = 1.0 - e_p2; - - double a = h*h*total_mass/( CONST_G*child1_mass*child2_mass*child1_mass*child2_mass*j_p2 ); - - double cos_f = cos(true_anomaly); - double sin_f = sin(true_anomaly); - - double r_norm = a*j_p2/(1.0 + e*cos_f); - double v_norm = sqrt( CONST_G*total_mass/(a*j_p2) ); - - for (i=0; i<3; i++) - { - r[i] = r_norm*( cos_f*e_vec_unit[i] + sin_f*q_vec_unit[i]); - v[i] = v_norm*( -sin_f*e_vec_unit[i] + (e + cos_f)*q_vec_unit[i] ); - } -} - -void from_cartesian_to_orbital_vectors(double child1_mass, double child2_mass, double r[3], double v[3], double e_vec[3], double h_vec[3]) -{ - double total_mass = child1_mass + child2_mass; - - double v_dot_v = dot3(v,v); - double r_dot_v = dot3(r,v); - double r_norm = norm3(r); - for (int i=0; i<3; i++) - { - e_vec[i] = (r[i]*v_dot_v - v[i]*r_dot_v)/(CONST_G*total_mass) - r[i]/r_norm; - } - - double mu = child1_mass*child2_mass/total_mass; - cross3(r,v,h_vec); - for (int i=0; i<3; i++) - { - h_vec[i] *= mu; - } -} - - -int get_de_dt(int index_of_the_particle, double *de_dt) -{ - - if (index_of_the_particle > highest_particle_index) - { - return -1; - } - - Particle * p = particlesMap[index_of_the_particle]; - if (p->is_binary == 0) - { - *de_dt = 0.0; - return 0; - } - - *de_dt = dot3(p->e_vec_unit,p->de_vec_dt); - - return 0; -} - - - -void get_position_and_velocity_vectors_from_particle(Particle *p, double r[3], double v[3]) -{ - r[0] = p->position_x; - r[1] = p->position_y; - r[2] = p->position_z; - v[0] = p->velocity_x; - v[1] = p->velocity_y; - v[2] = p->velocity_z; -} -void set_position_and_velocity_vectors_in_particle(Particle *p, double r[3], double v[3]) -{ - p->position_x = r[0]; - p->position_y = r[1]; - p->position_z = r[2]; - p->velocity_x = v[0]; - p->velocity_y = v[1]; - p->velocity_z = v[2]; -} -void get_e_and_h_vectors_from_particle(Particle *p, double e_vec[3], double h_vec[3]) -{ - e_vec[0] = p->e_vec_x; - e_vec[1] = p->e_vec_y; - e_vec[2] = p->e_vec_z; - h_vec[0] = p->h_vec_x; - h_vec[1] = p->h_vec_y; - h_vec[2] = p->h_vec_z; -} -void set_e_and_h_vectors_in_particle(Particle *p, double e_vec[3], double h_vec[3]) -{ - p->e_vec_x = e_vec[0]; - p->e_vec_y = e_vec[1]; - p->e_vec_z = e_vec[2]; - p->h_vec_x = h_vec[0]; - p->h_vec_y = h_vec[1]; - p->h_vec_z = h_vec[2]; -} - - -/************************ -/* interface parameters * - ************************/ - -int get_relative_tolerance(double *value) -{ - *value = relative_tolerance; - return 0; -} -int set_relative_tolerance(double value) -{ - relative_tolerance = value; - return 0; -} -int get_absolute_tolerance_eccentricity_vectors(double *value) -{ - *value = absolute_tolerance_eccentricity_vectors; - return 0; -} -int set_absolute_tolerance_eccentricity_vectors(double value) -{ - absolute_tolerance_eccentricity_vectors = value; - return 0; -} - -int get_include_quadrupole_order_terms(bool *value){ - *value = include_quadrupole_order_terms; - return 0; -} -int set_include_quadrupole_order_terms(bool value){ - include_quadrupole_order_terms = value; - return 0; -} - -int get_include_octupole_order_binary_pair_terms(bool *value){ - *value = include_octupole_order_binary_pair_terms; - return 0; -} -int set_include_octupole_order_binary_pair_terms(bool value){ - include_octupole_order_binary_pair_terms = value; - return 0; -} - -int get_include_octupole_order_binary_triplet_terms(bool *value){ - *value = include_octupole_order_binary_triplet_terms; - return 0; -} -int set_include_octupole_order_binary_triplet_terms(bool value){ - include_octupole_order_binary_triplet_terms = value; - return 0; -} - -int get_include_hexadecupole_order_binary_pair_terms(bool *value){ - *value = include_hexadecupole_order_binary_pair_terms; - return 0; -} -int set_include_hexadecupole_order_binary_pair_terms(bool value){ - include_hexadecupole_order_binary_pair_terms = value; - return 0; -} - -int get_include_dotriacontupole_order_binary_pair_terms(bool *value){ - *value = include_dotriacontupole_order_binary_pair_terms; - return 0; -} -int set_include_dotriacontupole_order_binary_pair_terms(bool value){ - include_dotriacontupole_order_binary_pair_terms = value; - return 0; -} - -int get_orbital_phases_random_seed(int *value) -{ - *value = orbital_phases_random_seed; - return 0; -} -int set_orbital_phases_random_seed(int value) -{ - orbital_phases_random_seed = value; - return 0; -} diff --git a/src/amuse/community/secularmultiple/interface.h b/src/amuse/community/secularmultiple/interface.h deleted file mode 100644 index ca89595ff3..0000000000 --- a/src/amuse/community/secularmultiple/interface.h +++ /dev/null @@ -1,266 +0,0 @@ -#include "src/types.h" - -/******************* -/* basic interface * - ******************/ -int new_particle(int * index_of_the_particle, bool is_binary); -int delete_particle(int index_of_the_particle); - -int set_children(int index_of_the_particle, int child1, int child2); -int get_children(int index_of_the_particle, int *child1, int *child2); - -int set_mass(int index_of_the_particle, double value); -int get_mass(int index_of_the_particle, double *value); - -int set_mass_dot_external(int index_of_the_particle, double value); -int get_mass_dot_external(int index_of_the_particle, double *value); - -int set_radius(int index_of_the_particle, double value); -int get_radius(int index_of_the_particle, double *value); - -int set_radius_dot_external(int index_of_the_particle, double value); -int get_radius_dot_external(int index_of_the_particle, double *value); - -int set_radius_ddot_external(int index_of_the_particle, double value); -int get_radius_ddot_external(int index_of_the_particle, double *value); - -int get_level(int index_of_the_particle, int *level); - -int set_stellar_type(int index_of_the_particle, int value); -int get_stellar_type(int index_of_the_particle, int *stellar_type); - -int set_true_anomaly(int index_of_the_particle, double value); -int get_true_anomaly(int index_of_the_particle, double *value); - -int set_sample_orbital_phases_randomly(int index_of_the_particle, bool value); -int get_sample_orbital_phases_randomly(int index_of_the_particle, bool *value); - - -/******************************* - * instantaneous perturbations * - * ****************************/ - -int set_instantaneous_perturbation_delta_mass(int index_of_the_particle, double value); -int get_instantaneous_perturbation_delta_mass(int index_of_the_particle, double *value); - -int set_instantaneous_perturbation_delta_position(int index_of_the_particle, double x, double y, double z); -int get_instantaneous_perturbation_delta_position(int index_of_the_particle, double *x, double *y, double *z); - -int set_instantaneous_perturbation_delta_velocity(int index_of_the_particle, double x, double y, double z); -int get_instantaneous_perturbation_delta_velocity(int index_of_the_particle, double *x, double *y, double *z); - - -/************ - * external * - * *********/ - -int new_external_particle(int * index_of_the_particle, double mass); -int delete_external_particle(int index_of_the_particle); - -int set_external_mass(int index_of_the_particle, double value); -int get_external_mass(int index_of_the_particle, double *value); - -int set_external_path(int index_of_the_external_particle, int value); -int get_external_path(int index_of_the_external_particle, int *value); - -int set_external_mode(int index_of_the_external_particle, int value); -int get_external_mode(int index_of_the_external_particle, int *value); - -int set_external_t_ref(int index_of_the_particle, double value); -int get_external_t_ref(int index_of_the_particle, double *value); - -int set_external_t_passed(int index_of_the_external_particle, double value); -int get_external_t_passed(int index_of_the_external_particle, double *value); - -int set_external_r0_vectors(int index_of_the_particle, double vec_x, double vec_y, double vec_z); -int get_external_r0_vectors(int index_of_the_particle, double *vec_x, double *vec_y, double *vec_z); - -int set_external_rdot_vectors(int index_of_the_external_particle, double rdot_vec_x, double rdot_vec_y, double rdot_vec_z); -int get_external_rdot_vectors(int index_of_the_external_particle, double *rdot_vec_x, double *rdot_vec_y, double *rdot_vec_z); - -int set_external_periapse_distance(int index_of_the_external_particle, double value); -int get_external_periapse_distance(int index_of_the_external_particle, double *value); - -int set_external_eccentricity(int index_of_the_external_particle, double value); -int get_external_eccentricity(int index_of_the_external_particle, double *value); - -int set_external_e_hat_vectors(int index_of_the_external_particle, double x, double y, double z); -int get_external_e_hat_vectors(int index_of_the_external_particle, double *x, double *y, double *z); - -int set_external_h_hat_vectors(int index_of_the_external_particle, double x, double y, double z); -int get_external_h_hat_vectors(int index_of_the_external_particle, double *x, double *y, double *z); - -int get_external_r_vectors(int index_of_the_external_particle, double *r_vec_x, double *r_vec_y, double *r_vec_z); - -/**************** -/* spin vectors * - ****************/ -int set_spin_vector(int index_of_the_particle, double spin_vec_x, double spin_vec_y, double spin_vec_z); -int get_spin_vector(int index_of_the_particle, double *spin_vec_x, double *spin_vec_y, double *spin_vec_z); - -int set_spin_vector_dot_external(int index_of_the_particle, double spin_vec_x_dot_external, double spin_vec_y_dot_external, double spin_vec_z_dot_external); -int get_spin_vector_dot_external(int index_of_the_particle, double *spin_vec_x_dot_external, double *spin_vec_y_dot_external, double *spin_vec_z_dot_external); - -/**************************** -/* orbital vectors/elements * - ****************************/ -int set_orbital_vectors(int index_of_the_particle, double e_vec_x, double e_vec_y, double e_vec_z, \ - double h_vec_x, double h_vec_y, double h_vec_z); -int get_orbital_vectors(int index_of_the_particle, double *e_vec_x, double *e_vec_y, double *e_vec_z, \ - double *h_vec_x, double *h_vec_y, double *h_vec_z); - -int set_orbital_vectors_dot_external(int index_of_the_particle, double e_vec_x_dot_external, double e_vec_y_dot_external, double e_vec_z_dot_external, \ - double h_vec_x_dot_external, double h_vec_y_dot_external, double h_vec_z_dot_external); -int get_orbital_vectors_dot_external(int index_of_the_particle, double *e_vec_x_dot_external, double *e_vec_y_dot_external, double *e_vec_z_dot_external, \ - double *h_vec_x_dot_external, double *h_vec_y_dot_external, double *h_vec_z_dot_external); - -int set_orbital_elements(int index_of_the_particle, double semimajor_axis, double eccentricity, \ - double inclination, double argument_of_pericenter, double longitude_of_ascending_node); -int get_orbital_elements(int index_of_the_particle, double *semimajor_axis, double *eccentricity, \ - double *inclination, double *argument_of_pericenter, double *longitude_of_ascending_node); - - -int set_position_vector(int index_of_the_particle, double x, double y, double z); -int get_position_vector(int index_of_the_particle, double *x, double *y, double *z); - -int set_velocity_vector(int index_of_the_particle, double x, double y, double z); -int get_velocity_vector(int index_of_the_particle, double *x, double *y, double *z); - - -/************ -/* PN terms * - ************/ -int set_include_pairwise_1PN_terms(int index_of_the_particle, bool include_pairwise_1PN_terms); -int get_include_pairwise_1PN_terms(int index_of_the_particle, bool *include_pairwise_1PN_terms); -int set_include_pairwise_25PN_terms(int index_of_the_particle, bool include_pairwise_25PN_terms); -int get_include_pairwise_25PN_terms(int index_of_the_particle, bool *include_pairwise_25PN_terms); - -/********* -/* tides * - *********/ -int set_include_tidal_friction_terms(int index_of_the_particle, bool include_tidal_friction_terms); -int get_include_tidal_friction_terms(int index_of_the_particle, bool *include_tidal_friction_terms); -int set_tides_method(int index_of_the_particle, int tides_method); -int get_tides_method(int index_of_the_particle, int *tides_method); -int set_include_tidal_bulges_precession_terms(int index_of_the_particle, bool include_tidal_bulges_precession_terms); -int get_include_tidal_bulges_precession_terms(int index_of_the_particle, bool *include_tidal_bulges_precession_terms); -int set_include_rotation_precession_terms(int index_of_the_particle, bool include_rotation_precession_terms); -int get_include_rotation_precession_terms(int index_of_the_particle, bool *include_rotation_precession_terms); -int set_minimum_eccentricity_for_tidal_precession(int index_of_the_particle, double minimum_eccentricity_for_tidal_precession); -int get_minimum_eccentricity_for_tidal_precession(int index_of_the_particle, double *minimum_eccentricity_for_tidal_precession); -int set_tides_apsidal_motion_constant(int index_of_the_particle, double value); -int get_tides_apsidal_motion_constant(int index_of_the_particle, double *value); -int set_tides_gyration_radius(int index_of_the_particle, double value); -int get_tides_gyration_radius(int index_of_the_particle, double *value); -int set_tides_viscous_time_scale(int index_of_the_particle, double value); -int get_tides_viscous_time_scale(int index_of_the_particle, double *value); -int set_tides_viscous_time_scale_prescription(int index_of_the_particle, int value); -int get_tides_viscous_time_scale_prescription(int index_of_the_particle, int *value); -int set_convective_envelope_mass(int index_of_the_particle, double value); -int get_convective_envelope_mass(int index_of_the_particle, double *value); -int set_convective_envelope_radius(int index_of_the_particle, double value); -int get_convective_envelope_radius(int index_of_the_particle, double *value); -int set_luminosity(int index_of_the_particle, double luminosity); -int get_luminosity(int index_of_the_particle, double *luminosity); - - -/**************** -/* root finding * - ****************/ - -int set_check_for_secular_breakdown(int index_of_the_particle, bool value); -int get_check_for_secular_breakdown(int index_of_the_particle, bool* value); - -int set_check_for_dynamical_instability(int index_of_the_particle, bool value); -int get_check_for_dynamical_instability(int index_of_the_particle, bool* value); -int set_dynamical_instability_criterion(int index_of_the_particle, int value); -int get_dynamical_instability_criterion(int index_of_the_particle, int* value); -int set_dynamical_instability_central_particle(int index_of_the_particle, int value); -int get_dynamical_instability_central_particle(int index_of_the_particle, int* value); -int set_dynamical_instability_K_parameter(int index_of_the_particle, double value); -int get_dynamical_instability_K_parameter(int index_of_the_particle, double* value); - -int set_check_for_physical_collision_or_orbit_crossing(int index_of_the_particle, bool value); -int get_check_for_physical_collision_or_orbit_crossing(int index_of_the_particle, bool* value); - -int set_check_for_minimum_periapse_distance(int index_of_the_particle, bool value); -int get_check_for_minimum_periapse_distance(int index_of_the_particle, bool* value); -int set_check_for_minimum_periapse_distance_value(int index_of_the_particle, double value); -int get_check_for_minimum_periapse_distance_value(int index_of_the_particle, double* value); - -int set_check_for_RLOF_at_pericentre(int index_of_the_particle, bool value); -int get_check_for_RLOF_at_pericentre(int index_of_the_particle, bool* value); -int set_check_for_RLOF_at_pericentre_use_sepinsky_fit(int index_of_the_particle, bool value); -int get_check_for_RLOF_at_pericentre_use_sepinsky_fit(int index_of_the_particle, bool* value); - -int set_root_finding_state(int index_of_the_particle, bool secular_breakdown_has_occurred, bool dynamical_instability_has_occurred, bool physical_collision_or_orbit_crossing_has_occurred, bool minimum_periapse_distance_has_occurred, bool RLOF_at_pericentre_has_occurred); -int get_root_finding_state(int index_of_the_particle, bool *secular_breakdown_has_occurred, bool *dynamical_instability_has_occurred, bool *physical_collision_or_orbit_crossing_has_occurred, bool* minimum_periapse_distance_has_occurred, bool *RLOF_at_pericentre_has_occurred); - - -/*********************** -/* interface functions * - ***********************/ -int evolve_interface(double start_time, double time_step, double *output_time, double *hamiltonian, int *flag, int *error_code); -int determine_binary_parents_levels_and_masses_interface(); -int apply_external_perturbation_assuming_integrated_orbits_interface(); -int apply_user_specified_instantaneous_perturbation_interface(); -int set_positions_and_velocities_interface(); - -/********************************************** -/* orbital element/vector conversion routines * - **********************************************/ -void compute_h_tot_vector(ParticlesMap* particlesMap, double h_tot_vector[3]); -int compute_orbital_vectors_from_orbital_elements(double child1_mass, double child2_mass, double semimajor_axis, double eccentricity, double inclination, double argument_of_pericenter,double longitude_of_ascending_node, double *e_vec_x, double *e_vec_y, double *e_vec_z, double *h_vec_x, double *h_vec_y, double *h_vec_z); -int compute_orbital_elements_from_orbital_vectors(double child1_mass, double child2_mass, double h_tot_vec[3], double e_vec_x, double e_vec_y, double e_vec_z, double h_vec_x, double h_vec_y, double h_vec_z, double *semimajor_axis, double *eccentricity, double *inclination, double *argument_of_pericenter,double *longitude_of_ascending_node); -int get_inclination_relative_to_parent(int index_of_the_particle, double *inclination_relative_to_parent); - -void compute_eccentric_anomaly_from_mean_anomaly(double mean_anomaly, double eccentricity, double *cos_eccentric_anomaly, double *sin_eccentric_anomaly); -void compute_true_anomaly_from_eccentric_anomaly(double cos_eccentric_anomaly, double sin_eccentric_anomaly, double eccentricity, double *cos_true_anomaly, double *sin_true_anomaly); -double compute_true_anomaly_from_mean_anomaly(double mean_anomaly, double eccentricity); -double sample_random_true_anomaly(double eccentricity,int seed); - -void from_orbital_vectors_to_cartesian(double child1_mass, double child2_mass, double e_vec[3], double h_vec[3], double true_anomaly, double r[3], double v[3]); -void from_cartesian_to_orbital_vectors(double child1_mass, double child2_mass, double r[3], double v[3], double e_vec[3], double h_vec[3]); - -int get_de_dt(int index_of_the_particle, double *de_dt); - -void get_position_and_velocity_vectors_from_particle(Particle *p, double r[3], double v[3]); -void set_position_and_velocity_vectors_in_particle(Particle *p, double r[3], double v[3]); -void get_e_and_h_vectors_from_particle(Particle *p, double e_vec[3], double h_vec[3]); -void set_e_and_h_vectors_in_particle(Particle *p, double e_vec[3], double h_vec[3]); - -/************************ -/* interface parameters * - ************************/ -extern double relative_tolerance; -extern double absolute_tolerance_eccentricity_vectors; -extern bool include_quadrupole_order_terms; -extern bool include_octupole_order_binary_pair_terms; -extern bool include_octupole_order_binary_triplet_terms; -extern bool include_hexadecupole_order_binary_pair_terms; -extern bool include_dotriacontupole_order_binary_pair_terms; -extern int orbital_phases_random_seed; - -int get_relative_tolerance(double *value); -int set_relative_tolerance(double value); - -int get_absolute_tolerance_eccentricity_vectors(double *value); -int set_absolute_tolerance_eccentricity_vectors(double value); - -int get_include_quadrupole_order_terms(bool *value); -int set_include_quadrupole_order_terms(bool value); - -int get_include_octupole_order_binary_pair_terms(bool *value); -int set_include_octupole_order_binary_pair_terms(bool value); - -int get_include_octupole_order_binary_triplet_terms(bool *value); -int set_include_octupole_order_binary_triplet_terms(bool value); - -int get_include_hexadecupole_order_binary_pair_terms(bool *value); -int set_include_hexadecupole_order_binary_pair_terms(bool value); - -int get_include_dotriacontupole_order_binary_pair_terms(bool *value); -int set_include_dotriacontupole_order_binary_pair_terms(bool value); - -int get_orbital_phases_random_seed(int *value); -int set_orbital_phases_random_seed(int value); diff --git a/src/amuse/community/secularmultiple/interface.py b/src/amuse/community/secularmultiple/interface.py index de16c9abdc..1a928b5e26 100644 --- a/src/amuse/community/secularmultiple/interface.py +++ b/src/amuse/community/secularmultiple/interface.py @@ -21,7 +21,8 @@ class SecularMultipleInterface(CodeInterface): November 2017: Updates for external perturbations (flybys & supernovae), detailed in Hamers (2018, in prep) """ - include_headers = ['interface.h','src/types.h','src/evolve.h','src/ODE_system.h'] + include_headers = ['worker_code.h'] + #~ include_headers = ['interface.h','src/types.h','src/evolve.h','src/ODE_system.h'] def __init__(self, **options): # CodeInterface.__init__(self, name_of_the_worker="secularmultiple_worker", **options) @@ -33,11 +34,12 @@ def __init__(self, **options): ### particles ### @legacy_function - def new_particle(): + def add_particle(): function = LegacyFunctionSpecification() function.can_handle_array = True function.addParameter('index_of_the_particle', dtype='int32', direction=function.OUT, unit=INDEX) function.addParameter('is_binary', dtype='bool', direction=function.IN, unit=NO_UNIT) + function.addParameter('is_external', dtype='bool', direction=function.IN, unit=NO_UNIT) function.result_type = 'int32' return function @@ -88,20 +90,20 @@ def get_mass(): return function @legacy_function - def set_mass_dot_external(): + def set_mass_dot(): function = LegacyFunctionSpecification() function.can_handle_array = True function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('mass_dot_external', dtype='float64', direction=function.IN, unit=unit_m/unit_t) + function.addParameter('mass_dot', dtype='float64', direction=function.IN, unit=unit_m/unit_t) function.result_type = 'int32' return function @legacy_function - def get_mass_dot_external(): + def get_mass_dot(): function = LegacyFunctionSpecification() function.can_handle_array = True function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('mass_dot_external', dtype='float64', direction=function.OUT, unit=unit_m/unit_t) + function.addParameter('mass_dot', dtype='float64', direction=function.OUT, unit=unit_m/unit_t) function.result_type = 'int32' return function @@ -111,1109 +113,783 @@ def set_radius(): function.can_handle_array = True function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) function.addParameter('radius', dtype='float64', direction=function.IN, unit=unit_l) - function.result_type = 'int32' - return function - - @legacy_function - def get_radius(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('radius', dtype='float64', direction=function.OUT, unit=unit_l) - function.result_type = 'int32' - return function - - @legacy_function - def set_radius_dot_external(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) function.addParameter('radius_dot_external', dtype='float64', direction=function.IN, unit=unit_l/unit_t) function.result_type = 'int32' return function - - @legacy_function - def get_radius_dot_external(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('radius_dot_external', dtype='float64', direction=function.OUT, unit=unit_l/unit_t) - function.result_type = 'int32' - return function - - @legacy_function - def set_radius_ddot_external(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('radius_ddot_external', dtype='float64', direction=function.IN, unit=unit_l/(unit_t**2)) - function.result_type = 'int32' - return function - - @legacy_function - def get_radius_ddot_external(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('radius_ddot_external', dtype='float64', direction=function.OUT, unit=unit_l/(unit_t**2)) - function.result_type = 'int32' - return function - - @legacy_function - def get_level(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('level', dtype='int32', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_stellar_type(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('stellar_type', dtype='int32', direction=function.IN, unit=units.stellar_type) - function.result_type = 'int32' - return function - - @legacy_function - def get_stellar_type(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('stellar_type', dtype='int32', direction=function.OUT, unit=units.stellar_type) - function.result_type = 'int32' - return function - - - @legacy_function - def set_true_anomaly(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('true_anomaly', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_true_anomaly(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('true_anomaly', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - - @legacy_function - def set_sample_orbital_phases_randomly(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('sample_orbital_phases_randomly', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_sample_orbital_phases_randomly(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('sample_orbital_phases_randomly', dtype='bool', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - - - - ################################################# - ### user-specified instantaneous perturbation ### - ################################################# - - @legacy_function - def set_instantaneous_perturbation_delta_mass(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('instantaneous_perturbation_delta_mass', dtype='float64', direction=function.IN, unit=unit_m) - function.result_type = 'int32' - return function - - @legacy_function - def get_instantaneous_perturbation_delta_mass(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('instantaneous_perturbation_delta_mass', dtype='float64', direction=function.OUT, unit=unit_m) - function.result_type = 'int32' - return function - - - @legacy_function - def set_instantaneous_perturbation_delta_position(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('instantaneous_perturbation_delta_position_x',dtype='float64', direction=function.IN, unit=unit_l) - function.addParameter('instantaneous_perturbation_delta_position_y',dtype='float64', direction=function.IN, unit=unit_l) - function.addParameter('instantaneous_perturbation_delta_position_z',dtype='float64', direction=function.IN, unit=unit_l) - function.result_type = 'int32' - return function - - @legacy_function - def get_instantaneous_perturbation_delta_position(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('instantaneous_perturbation_delta_position_x',dtype='float64', direction=function.OUT, unit=unit_l) - function.addParameter('instantaneous_perturbation_delta_position_y',dtype='float64', direction=function.OUT, unit=unit_l) - function.addParameter('instantaneous_perturbation_delta_position_z',dtype='float64', direction=function.OUT, unit=unit_l) - function.result_type = 'int32' - return function - - - @legacy_function - def set_instantaneous_perturbation_delta_velocity(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('instantaneous_perturbation_delta_velocity_x',dtype='float64', direction=function.IN, unit=unit_l/unit_t) - function.addParameter('instantaneous_perturbation_delta_velocity_y',dtype='float64', direction=function.IN, unit=unit_l/unit_t) - function.addParameter('instantaneous_perturbation_delta_velocity_z',dtype='float64', direction=function.IN, unit=unit_l/unit_t) - function.result_type = 'int32' - return function - - @legacy_function - def get_instantaneous_perturbation_delta_velocity(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('instantaneous_perturbation_delta_velocity_x',dtype='float64', direction=function.OUT, unit=unit_l/unit_t) - function.addParameter('instantaneous_perturbation_delta_velocity_y',dtype='float64', direction=function.OUT, unit=unit_l/unit_t) - function.addParameter('instantaneous_perturbation_delta_velocity_z',dtype='float64', direction=function.OUT, unit=unit_l/unit_t) - function.result_type = 'int32' - return function - - - - - ########################## - ### external particles ### - ########################## - - @legacy_function - def new_external_particle(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.OUT, unit=INDEX) - function.addParameter('mass', dtype='float64', direction=function.IN, unit=unit_m) - function.result_type = 'int32' - return function - - @legacy_function - def delete_external_particle(): - function = LegacyFunctionSpecification() - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.result_type = 'int32' - return function - - - @legacy_function - def set_external_mass(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('mass', dtype='float64', direction=function.IN, unit=unit_m) - function.result_type = 'int32' - return function - - @legacy_function - def get_external_mass(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('mass', dtype='float64', direction=function.OUT, unit=unit_m) - function.result_type = 'int32' - return function - - - @legacy_function - def set_external_path(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('path', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_external_path(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('path', dtype='int32', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - - @legacy_function - def set_external_mode(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('mode', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_external_mode(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('mode', dtype='int32', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - - @legacy_function - def set_external_t_ref(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('t_ref', dtype='float64', direction=function.IN, unit=unit_t) - function.result_type = 'int32' - return function - - @legacy_function - def get_external_t_ref(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('t_ref', dtype='float64', direction=function.OUT, unit=unit_t) - function.result_type = 'int32' - return function - - @legacy_function - def set_external_t_passed(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('t_passed', dtype='float64', direction=function.IN, unit=unit_t) - function.result_type = 'int32' - return function - - @legacy_function - def get_external_t_passed(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('t_passed', dtype='float64', direction=function.OUT, unit=unit_t) - function.result_type = 'int32' - return function - - @legacy_function - def set_external_r0_vectors(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('r0_vec_x', dtype='float64', direction=function.IN, unit=unit_l) - function.addParameter('r0_vec_y', dtype='float64', direction=function.IN, unit=unit_l) - function.addParameter('r0_vec_z', dtype='float64', direction=function.IN, unit=unit_l) - function.result_type = 'int32' - return function - - @legacy_function - def get_external_r0_vectors(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('r0_vec_x', dtype='float64', direction=function.OUT, unit=unit_l) - function.addParameter('r0_vec_y', dtype='float64', direction=function.OUT, unit=unit_l) - function.addParameter('r0_vec_z', dtype='float64', direction=function.OUT, unit=unit_l) - function.result_type = 'int32' - return function - - - @legacy_function - def set_external_rdot_vectors(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('rdot_vec_x', dtype='float64', direction=function.IN, unit=unit_l/unit_t) - function.addParameter('rdot_vec_y', dtype='float64', direction=function.IN, unit=unit_l/unit_t) - function.addParameter('rdot_vec_z', dtype='float64', direction=function.IN, unit=unit_l/unit_t) - function.result_type = 'int32' - return function - - @legacy_function - def get_external_rdot_vectors(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('rdot_vec_x', dtype='float64', direction=function.OUT, unit=unit_l/unit_t) - function.addParameter('rdot_vec_y', dtype='float64', direction=function.OUT, unit=unit_l/unit_t) - function.addParameter('rdot_vec_z', dtype='float64', direction=function.OUT, unit=unit_l/unit_t) - function.result_type = 'int32' - return function - - - @legacy_function - def set_external_periapse_distance(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('periapse_distance', dtype='float64', direction=function.IN, unit=unit_l) - function.result_type = 'int32' - return function - - @legacy_function - def get_external_periapse_distance(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('periapse_distance', dtype='float64', direction=function.OUT, unit=unit_l) - function.result_type = 'int32' - return function - - - @legacy_function - def set_external_eccentricity(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('eccentricity', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_external_eccentricity(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('eccentricity', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - - @legacy_function - def set_external_e_hat_vectors(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('e_hat_vec_x', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.addParameter('e_hat_vec_y', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.addParameter('e_hat_vec_z', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_external_e_hat_vectors(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('e_hat_vec_x', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.addParameter('e_hat_vec_y', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.addParameter('e_hat_vec_z', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - - @legacy_function - def set_external_h_hat_vectors(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('h_hat_vec_x', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.addParameter('h_hat_vec_y', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.addParameter('h_hat_vec_z', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_external_h_hat_vectors(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('h_hat_vec_x', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.addParameter('h_hat_vec_y', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.addParameter('h_hat_vec_z', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - - @legacy_function - def get_external_r_vectors(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('r_vec_x', dtype='float64', direction=function.OUT, unit=unit_l) - function.addParameter('r_vec_y', dtype='float64', direction=function.OUT, unit=unit_l) - function.addParameter('r_vec_z', dtype='float64', direction=function.OUT, unit=unit_l) - function.result_type = 'int32' - return function - - - - #################### - ### spin vectors ### - #################### - - @legacy_function - def set_spin_vector(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('spin_vec_x', dtype='float64', direction=function.IN, unit=1.0/unit_t) - function.addParameter('spin_vec_y', dtype='float64', direction=function.IN, unit=1.0/unit_t) - function.addParameter('spin_vec_z', dtype='float64', direction=function.IN, unit=1.0/unit_t) - function.result_type = 'int32' - return function - - @legacy_function - def get_spin_vector(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('spin_vec_x', dtype='float64', direction=function.OUT, unit=1.0/unit_t) - function.addParameter('spin_vec_y', dtype='float64', direction=function.OUT, unit=1.0/unit_t) - function.addParameter('spin_vec_z', dtype='float64', direction=function.OUT, unit=1.0/unit_t) - function.result_type = 'int32' - return function - - @legacy_function - def set_spin_vector_dot_external(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('spin_vec_x_dot_external',dtype='float64', direction=function.IN, unit=1.0/(unit_t**2)) - function.addParameter('spin_vec_y_dot_external',dtype='float64', direction=function.IN, unit=1.0/(unit_t**2)) - function.addParameter('spin_vec_z_dot_external',dtype='float64', direction=function.IN, unit=1.0/(unit_t**2)) - function.result_type = 'int32' - return function - - @legacy_function - def get_spin_vector_dot_external(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('spin_vec_x_dot_external',dtype='float64', direction=function.OUT, unit=1.0/(unit_t**2)) - function.addParameter('spin_vec_y_dot_external',dtype='float64', direction=function.OUT, unit=1.0/(unit_t**2)) - function.addParameter('spin_vec_z_dot_external',dtype='float64', direction=function.OUT, unit=1.0/(unit_t**2)) - function.result_type = 'int32' - return function - - - ################################ - ### orbital vectors/elements ### - ################################ - - @legacy_function - def set_orbital_vectors(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('e_vec_x', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.addParameter('e_vec_y', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.addParameter('e_vec_z', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.addParameter('h_vec_x', dtype='float64', direction=function.IN, unit=unit_h) - function.addParameter('h_vec_y', dtype='float64', direction=function.IN, unit=unit_h) - function.addParameter('h_vec_z', dtype='float64', direction=function.IN, unit=unit_h) - function.result_type = 'int32' - return function - - @legacy_function - def get_orbital_vectors(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('e_vec_x', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.addParameter('e_vec_y', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.addParameter('e_vec_z', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.addParameter('h_vec_x', dtype='float64', direction=function.OUT, unit=unit_h) - function.addParameter('h_vec_y', dtype='float64', direction=function.OUT, unit=unit_h) - function.addParameter('h_vec_z', dtype='float64', direction=function.OUT, unit=unit_h) - function.result_type = 'int32' - return function - - @legacy_function - def set_orbital_vectors_dot_external(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('e_vec_x_dot_external', dtype='float64', direction=function.IN, unit=1.0/unit_t) - function.addParameter('e_vec_y_dot_external', dtype='float64', direction=function.IN, unit=1.0/unit_t) - function.addParameter('e_vec_z_dot_external', dtype='float64', direction=function.IN, unit=1.0/unit_t) - function.addParameter('h_vec_x_dot_external', dtype='float64', direction=function.IN, unit=unit_h/unit_t) - function.addParameter('h_vec_y_dot_external', dtype='float64', direction=function.IN, unit=unit_h/unit_t) - function.addParameter('h_vec_z_dot_external', dtype='float64', direction=function.IN, unit=unit_h/unit_t) - function.result_type = 'int32' - return function - - @legacy_function - def get_orbital_vectors_dot_external(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('e_vec_x_dot_external', dtype='float64', direction=function.OUT, unit=1.0/unit_t) - function.addParameter('e_vec_y_dot_external', dtype='float64', direction=function.OUT, unit=1.0/unit_t) - function.addParameter('e_vec_z_dot_external', dtype='float64', direction=function.OUT, unit=1.0/unit_t) - function.addParameter('h_vec_x_dot_external', dtype='float64', direction=function.OUT, unit=unit_h/unit_t) - function.addParameter('h_vec_y_dot_external', dtype='float64', direction=function.OUT, unit=unit_h/unit_t) - function.addParameter('h_vec_z_dot_external', dtype='float64', direction=function.OUT, unit=unit_h/unit_t) - function.result_type = 'int32' - return function - - - @legacy_function - def set_orbital_elements(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('semimajor_axis', dtype='float64', direction=function.IN, unit=unit_l) - function.addParameter('eccentricity', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.addParameter('inclination', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.addParameter('argument_of_pericenter', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.addParameter('longitude_of_ascending_node', dtype='float64',direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_orbital_elements(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('semimajor_axis', dtype='float64', direction=function.OUT, unit=unit_l) - function.addParameter('eccentricity', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.addParameter('inclination', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.addParameter('argument_of_pericenter', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.addParameter('longitude_of_ascending_node', dtype='float64',direction=function.OUT,unit=NO_UNIT) - function.result_type = 'int32' - return function - - - @legacy_function - def get_inclination_relative_to_parent(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('inclination_relative_to_parent',dtype='float64',direction=function.OUT,unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_de_dt(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('de_dt', dtype='float64', direction=function.OUT, unit=1.0/unit_t) - function.result_type = 'int32' - return function - - - - @legacy_function - def set_position_vector(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('position_x', dtype='float64', direction=function.IN, unit=unit_l) - function.addParameter('position_y', dtype='float64', direction=function.IN, unit=unit_l) - function.addParameter('position_z', dtype='float64', direction=function.IN, unit=unit_l) - function.result_type = 'int32' - return function - - @legacy_function - def get_position_vector(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('position_x', dtype='float64', direction=function.OUT, unit=unit_l) - function.addParameter('position_y', dtype='float64', direction=function.OUT, unit=unit_l) - function.addParameter('position_z', dtype='float64', direction=function.OUT, unit=unit_l) - function.result_type = 'int32' - return function - - - @legacy_function - def set_velocity_vector(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('velocity_x', dtype='float64', direction=function.IN, unit=unit_l/unit_t) - function.addParameter('velocity_y', dtype='float64', direction=function.IN, unit=unit_l/unit_t) - function.addParameter('velocity_z', dtype='float64', direction=function.IN, unit=unit_l/unit_t) - function.result_type = 'int32' - return function - - @legacy_function - def get_velocity_vector(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) - function.addParameter('velocity_x', dtype='float64', direction=function.OUT, unit=unit_l/unit_t) - function.addParameter('velocity_y', dtype='float64', direction=function.OUT, unit=unit_l/unit_t) - function.addParameter('velocity_z', dtype='float64', direction=function.OUT, unit=unit_l/unit_t) - function.result_type = 'int32' - return function - - - - - ################ - ### PN terms ### - ################ - - @legacy_function - def set_include_pairwise_1PN_terms(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('include_pairwise_1PN_terms', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_include_pairwise_1PN_terms(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('include_pairwise_1PN_terms', dtype='bool', direction=function.OUT,unit=NO_UNIT) - function.result_type = 'int32' - return function - - - @legacy_function - def set_include_pairwise_25PN_terms(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('include_pairwise_25PN_terms', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_include_pairwise_25PN_terms(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('include_pairwise_25PN_terms', dtype='bool', direction=function.OUT,unit=NO_UNIT) - function.result_type = 'int32' - return function - - - ############# - ### tides ### - ############# - - @legacy_function - def set_tides_method(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('tides_method', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_tides_method(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('tides_method', dtype='int32', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_include_tidal_friction_terms(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('include_tidal_friction_terms', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_include_tidal_friction_terms(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('include_tidal_friction_terms', dtype='bool', direction=function.OUT,unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_include_tidal_bulges_precession_terms(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('include_tidal_bulges_precession_terms', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_include_tidal_bulges_precession_terms(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('include_tidal_bulges_precession_terms', dtype='bool', direction=function.OUT,unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_include_rotation_precession_terms(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('include_rotation_precession_terms', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_include_rotation_precession_terms(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('include_rotation_precession_terms', dtype='bool', direction=function.OUT,unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_minimum_eccentricity_for_tidal_precession(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('minimum_eccentricity_for_tidal_precession', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_minimum_eccentricity_for_tidal_precession(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('minimum_eccentricity_for_tidal_precession', dtype='float64', direction=function.OUT,unit=NO_UNIT) - function.result_type = 'int32' - return function - - ### physical parameters ### - - @legacy_function - def set_tides_apsidal_motion_constant(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('tides_apsidal_motion_constant', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - @legacy_function - def get_tides_apsidal_motion_constant(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('tides_apsidal_motion_constant', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_tides_gyration_radius(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('tides_gyration_radius', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - @legacy_function - def get_tides_gyration_radius(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('tides_gyration_radius', dtype='float64', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_tides_viscous_time_scale(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('tides_viscous_time_scale', dtype='float64', direction=function.IN, unit=unit_t) - function.result_type = 'int32' - return function - @legacy_function - def get_tides_viscous_time_scale(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('tides_viscous_time_scale', dtype='float64', direction=function.OUT, unit=unit_t) - function.result_type = 'int32' - return function - - @legacy_function - def set_tides_viscous_time_scale_prescription(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('tides_viscous_time_scale_prescription', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - @legacy_function - def get_tides_viscous_time_scale_prescription(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('tides_viscous_time_scale_prescription', dtype='int32', direction=function.OUT,unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_convective_envelope_mass(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('convective_envelope_mass', dtype='float64', direction=function.IN, unit=unit_m) - function.result_type = 'int32' - return function - @legacy_function - def get_convective_envelope_mass(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('convective_envelope_mass', dtype='float64', direction=function.OUT, unit=unit_m) - function.result_type = 'int32' - return function - + @legacy_function - def set_convective_envelope_radius(): + def get_radius(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('convective_envelope_radius', dtype='float64', direction=function.IN, unit=unit_l) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('radius', dtype='float64', direction=function.OUT, unit=unit_l) + function.addParameter('radius_dot_external', dtype='float64', direction=function.OUT, unit=unit_l/unit_t) function.result_type = 'int32' return function + @legacy_function - def get_convective_envelope_radius(): + def get_level(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('convective_envelope_radius', dtype='float64', direction=function.OUT, unit=unit_l) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('level', dtype='int32', direction=function.OUT, unit=NO_UNIT) function.result_type = 'int32' return function - + @legacy_function - def set_luminosity(): + def set_stellar_type(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('luminosity', dtype='float64', direction=function.IN, unit=unit_lum) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('stellar_type', dtype='int32', direction=function.IN, unit=units.stellar_type) function.result_type = 'int32' return function + @legacy_function - def get_luminosity(): + def get_stellar_type(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('luminosity', dtype='float64', direction=function.OUT, unit=unit_lum) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('stellar_type', dtype='int32', direction=function.OUT, unit=units.stellar_type) function.result_type = 'int32' return function + #~ @legacy_function + #~ def set_true_anomaly(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + #~ function.addParameter('true_anomaly', dtype='float64', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_true_anomaly(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + #~ function.addParameter('true_anomaly', dtype='float64', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + + #~ @legacy_function + #~ def set_sample_orbital_phases_randomly(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + #~ function.addParameter('sample_orbital_phases_randomly', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_sample_orbital_phases_randomly(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + #~ function.addParameter('sample_orbital_phases_randomly', dtype='bool', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + + ################################################# + ### user-specified instantaneous perturbation ### + ################################################# + + #~ @legacy_function + #~ def set_instantaneous_perturbation(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + #~ function.addParameter('instantaneous_perturbation_delta_mass', dtype='float64', direction=function.IN, unit=unit_m) + #~ function.addParameter('instantaneous_perturbation_delta_position_x',dtype='float64', direction=function.IN, unit=unit_l) + #~ function.addParameter('instantaneous_perturbation_delta_position_y',dtype='float64', direction=function.IN, unit=unit_l) + #~ function.addParameter('instantaneous_perturbation_delta_position_z',dtype='float64', direction=function.IN, unit=unit_l) + #~ function.addParameter('instantaneous_perturbation_delta_velocity_x',dtype='float64', direction=function.IN, unit=unit_l/unit_t) + #~ function.addParameter('instantaneous_perturbation_delta_velocity_y',dtype='float64', direction=function.IN, unit=unit_l/unit_t) + #~ function.addParameter('instantaneous_perturbation_delta_velocity_z',dtype='float64', direction=function.IN, unit=unit_l/unit_t) + #~ function.result_type = 'int32' + #~ return function + + + #~ @legacy_function + #~ def set_external_properties(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_external_particle', dtype='int32', direction=function.IN, unit=INDEX) + #~ function.addParameter('mass', dtype='float64', direction=function.IN, unit=unit_m) + #~ function.addParameter('t_ref', dtype='float64', direction=function.IN, unit=unit_t) + #~ function.result_type = 'int32' + #~ return function + #~ function.addParameter('periapse_distance', dtype='float64', direction=function.OUT, unit=unit_l) + #~ function.addParameter('eccentricity', dtype='float64', direction=function.IN, unit=NO_UNIT) +# 3 more + + #################### - ### root finding ### + ### spin vectors ### #################### - ### secular breakdown ### @legacy_function - def set_check_for_secular_breakdown(): + def set_spin_vector(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_secular_breakdown', dtype='bool', direction=function.IN, unit=NO_UNIT) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('spin_vec_x', dtype='float64', direction=function.IN, unit=1.0/unit_t) + function.addParameter('spin_vec_y', dtype='float64', direction=function.IN, unit=1.0/unit_t) + function.addParameter('spin_vec_z', dtype='float64', direction=function.IN, unit=1.0/unit_t) function.result_type = 'int32' return function - + @legacy_function - def get_check_for_secular_breakdown(): + def get_spin_vector(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_secular_breakdown', dtype='bool', direction=function.OUT, unit=NO_UNIT) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('spin_vec_x', dtype='float64', direction=function.OUT, unit=1.0/unit_t) + function.addParameter('spin_vec_y', dtype='float64', direction=function.OUT, unit=1.0/unit_t) + function.addParameter('spin_vec_z', dtype='float64', direction=function.OUT, unit=1.0/unit_t) function.result_type = 'int32' - return function - + return function - ### dynamical instablity ### @legacy_function - def set_check_for_dynamical_instability(): + def set_spin_vector_dot(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_dynamical_instability',dtype='bool', direction=function.IN, unit=NO_UNIT) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('spin_vec_x_dot_external',dtype='float64', direction=function.IN, unit=1.0/(unit_t**2)) + function.addParameter('spin_vec_y_dot_external',dtype='float64', direction=function.IN, unit=1.0/(unit_t**2)) + function.addParameter('spin_vec_z_dot_external',dtype='float64', direction=function.IN, unit=1.0/(unit_t**2)) function.result_type = 'int32' return function - + @legacy_function - def get_check_for_dynamical_instability(): + def get_spin_vector_dot(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_dynamical_instability',dtype='bool', direction=function.OUT, unit=NO_UNIT) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('spin_vec_x_dot_external',dtype='float64', direction=function.OUT, unit=1.0/(unit_t**2)) + function.addParameter('spin_vec_y_dot_external',dtype='float64', direction=function.OUT, unit=1.0/(unit_t**2)) + function.addParameter('spin_vec_z_dot_external',dtype='float64', direction=function.OUT, unit=1.0/(unit_t**2)) function.result_type = 'int32' - return function + return function - @legacy_function - def set_dynamical_instability_criterion(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('dynamical_instability_criterion',dtype='int32', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - @legacy_function - def get_dynamical_instability_criterion(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('dynamical_instability_criterion',dtype='int32', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function + ################################ + ### orbital vectors/elements ### + ################################ @legacy_function - def set_dynamical_instability_central_particle(): + def set_orbital_vectors(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('dynamical_instability_central_particle', dtype='int32', direction=function.IN, unit=LINK('particles')) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('e_vec_x', dtype='float64', direction=function.IN, unit=NO_UNIT) + function.addParameter('e_vec_y', dtype='float64', direction=function.IN, unit=NO_UNIT) + function.addParameter('e_vec_z', dtype='float64', direction=function.IN, unit=NO_UNIT) + function.addParameter('h_vec_x', dtype='float64', direction=function.IN, unit=unit_h) + function.addParameter('h_vec_y', dtype='float64', direction=function.IN, unit=unit_h) + function.addParameter('h_vec_z', dtype='float64', direction=function.IN, unit=unit_h) function.result_type = 'int32' return function + + #~ @legacy_function + #~ def get_orbital_vectors(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + #~ function.addParameter('e_vec_x', dtype='float64', direction=function.OUT, unit=NO_UNIT) + #~ function.addParameter('e_vec_y', dtype='float64', direction=function.OUT, unit=NO_UNIT) + #~ function.addParameter('e_vec_z', dtype='float64', direction=function.OUT, unit=NO_UNIT) + #~ function.addParameter('h_vec_x', dtype='float64', direction=function.OUT, unit=unit_h) + #~ function.addParameter('h_vec_y', dtype='float64', direction=function.OUT, unit=unit_h) + #~ function.addParameter('h_vec_z', dtype='float64', direction=function.OUT, unit=unit_h) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_orbital_vectors_dot_external(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + #~ function.addParameter('e_vec_x_dot_external', dtype='float64', direction=function.IN, unit=1.0/unit_t) + #~ function.addParameter('e_vec_y_dot_external', dtype='float64', direction=function.IN, unit=1.0/unit_t) + #~ function.addParameter('e_vec_z_dot_external', dtype='float64', direction=function.IN, unit=1.0/unit_t) + #~ function.addParameter('h_vec_x_dot_external', dtype='float64', direction=function.IN, unit=unit_h/unit_t) + #~ function.addParameter('h_vec_y_dot_external', dtype='float64', direction=function.IN, unit=unit_h/unit_t) + #~ function.addParameter('h_vec_z_dot_external', dtype='float64', direction=function.IN, unit=unit_h/unit_t) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_orbital_vectors_dot_external(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + #~ function.addParameter('e_vec_x_dot_external', dtype='float64', direction=function.OUT, unit=1.0/unit_t) + #~ function.addParameter('e_vec_y_dot_external', dtype='float64', direction=function.OUT, unit=1.0/unit_t) + #~ function.addParameter('e_vec_z_dot_external', dtype='float64', direction=function.OUT, unit=1.0/unit_t) + #~ function.addParameter('h_vec_x_dot_external', dtype='float64', direction=function.OUT, unit=unit_h/unit_t) + #~ function.addParameter('h_vec_y_dot_external', dtype='float64', direction=function.OUT, unit=unit_h/unit_t) + #~ function.addParameter('h_vec_z_dot_external', dtype='float64', direction=function.OUT, unit=unit_h/unit_t) + #~ function.result_type = 'int32' + #~ return function + @legacy_function - def get_dynamical_instability_central_particle(): + def set_orbital_elements(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('dynamical_instability_central_particle', dtype='int32', direction=function.OUT, unit=LINK('particles')) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('semimajor_axis', dtype='float64', direction=function.IN, unit=unit_l) + function.addParameter('eccentricity', dtype='float64', direction=function.IN, unit=NO_UNIT) + function.addParameter('inclination', dtype='float64', direction=function.IN, unit=NO_UNIT) + function.addParameter('argument_of_pericenter', dtype='float64', direction=function.IN, unit=NO_UNIT) + function.addParameter('longitude_of_ascending_node', dtype='float64',direction=function.IN, unit=NO_UNIT) function.result_type = 'int32' return function @legacy_function - def set_dynamical_instability_K_parameter(): + def get_orbital_elements(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.addParameter('dynamical_instability_K_parameter', dtype='float64', direction=function.IN, unit=NO_UNIT) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('semimajor_axis', dtype='float64', direction=function.OUT, unit=unit_l) + function.addParameter('eccentricity', dtype='float64', direction=function.OUT, unit=NO_UNIT) + function.addParameter('inclination', dtype='float64', direction=function.OUT, unit=NO_UNIT) + function.addParameter('argument_of_pericenter', dtype='float64', direction=function.OUT, unit=NO_UNIT) + function.addParameter('longitude_of_ascending_node', dtype='float64',direction=function.OUT,unit=NO_UNIT) function.result_type = 'int32' - return function + return function + @legacy_function - def get_dynamical_instability_K_parameter(): + def get_inclination_relative_to_parent(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='float64', direction=function.IN, unit=NO_UNIT) - function.addParameter('dynamical_instability_K_parameter', dtype='float64', direction=function.OUT, unit=NO_UNIT) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('inclination_relative_to_parent',dtype='float64',direction=function.OUT,unit=NO_UNIT) function.result_type = 'int32' - return function - + return function - ### physical collision / orbit crossing ### @legacy_function - def set_check_for_physical_collision_or_orbit_crossing(): + def get_de_dt(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_physical_collision_or_orbit_crossing', dtype='bool', direction=function.IN, unit=NO_UNIT) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('de_dt', dtype='float64', direction=function.OUT, unit=1.0/unit_t) function.result_type = 'int32' - return function + return function - @legacy_function - def get_check_for_physical_collision_or_orbit_crossing(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_physical_collision_or_orbit_crossing', dtype='bool', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - ### minimum periapse distance reached ### @legacy_function - def set_check_for_minimum_periapse_distance(): + def set_position_vector(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_minimum_periapse_distance', dtype='bool', direction=function.IN, unit=NO_UNIT) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('position_x', dtype='float64', direction=function.IN, unit=unit_l) + function.addParameter('position_y', dtype='float64', direction=function.IN, unit=unit_l) + function.addParameter('position_z', dtype='float64', direction=function.IN, unit=unit_l) function.result_type = 'int32' return function - + @legacy_function - def get_check_for_minimum_periapse_distance(): + def get_position_vector(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_minimum_periapse_distance', dtype='bool', direction=function.OUT, unit=NO_UNIT) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('position_x', dtype='float64', direction=function.OUT, unit=unit_l) + function.addParameter('position_y', dtype='float64', direction=function.OUT, unit=unit_l) + function.addParameter('position_z', dtype='float64', direction=function.OUT, unit=unit_l) function.result_type = 'int32' - return function + return function + @legacy_function - def set_check_for_minimum_periapse_distance_value(): + def set_velocity_vector(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_minimum_periapse_distance_value', dtype='float64', direction=function.IN, unit=unit_l) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('velocity_x', dtype='float64', direction=function.IN, unit=unit_l/unit_t) + function.addParameter('velocity_y', dtype='float64', direction=function.IN, unit=unit_l/unit_t) + function.addParameter('velocity_z', dtype='float64', direction=function.IN, unit=unit_l/unit_t) function.result_type = 'int32' return function - + @legacy_function - def get_check_for_minimum_periapse_distance_value(): + def get_velocity_vector(): function = LegacyFunctionSpecification() function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_minimum_periapse_distance_value', dtype='float64', direction=function.OUT, unit=unit_l) + function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=INDEX) + function.addParameter('velocity_x', dtype='float64', direction=function.OUT, unit=unit_l/unit_t) + function.addParameter('velocity_y', dtype='float64', direction=function.OUT, unit=unit_l/unit_t) + function.addParameter('velocity_z', dtype='float64', direction=function.OUT, unit=unit_l/unit_t) function.result_type = 'int32' - return function + return function - ### RLOF at pericentre ### - @legacy_function - def set_check_for_RLOF_at_pericentre(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_RLOF_at_pericentre', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - @legacy_function - def get_check_for_RLOF_at_pericentre(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_RLOF_at_pericentre', dtype='bool', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - @legacy_function - def set_check_for_RLOF_at_pericentre_use_sepinsky_fit(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_RLOF_at_pericentre_use_sepinsky_fit', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function + ################ + ### PN terms ### + ################ + + #~ @legacy_function + #~ def set_include_pairwise_1PN_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('include_pairwise_1PN_terms', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_include_pairwise_1PN_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('include_pairwise_1PN_terms', dtype='bool', direction=function.OUT,unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + + #~ @legacy_function + #~ def set_include_pairwise_25PN_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('include_pairwise_25PN_terms', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_include_pairwise_25PN_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('include_pairwise_25PN_terms', dtype='bool', direction=function.OUT,unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function - @legacy_function - def get_check_for_RLOF_at_pericentre_use_sepinsky_fit(): - function = LegacyFunctionSpecification() - function.can_handle_array = True - function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) - function.addParameter('check_for_RLOF_at_pericentre_use_sepinsky_fit', dtype='bool', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function + + ############# + ### tides ### + ############# + + #~ @legacy_function + #~ def set_tides_method(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('tides_method', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_tides_method(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('tides_method', dtype='int32', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_include_tidal_friction_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('include_tidal_friction_terms', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_include_tidal_friction_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('include_tidal_friction_terms', dtype='bool', direction=function.OUT,unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_include_tidal_bulges_precession_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('include_tidal_bulges_precession_terms', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_include_tidal_bulges_precession_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('include_tidal_bulges_precession_terms', dtype='bool', direction=function.OUT,unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_include_rotation_precession_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('include_rotation_precession_terms', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_include_rotation_precession_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('include_rotation_precession_terms', dtype='bool', direction=function.OUT,unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_minimum_eccentricity_for_tidal_precession(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('minimum_eccentricity_for_tidal_precession', dtype='float64', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_minimum_eccentricity_for_tidal_precession(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('minimum_eccentricity_for_tidal_precession', dtype='float64', direction=function.OUT,unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + ### physical parameters ### + + #~ @legacy_function + #~ def set_tides_apsidal_motion_constant(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('tides_apsidal_motion_constant', dtype='float64', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + #~ @legacy_function + #~ def get_tides_apsidal_motion_constant(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('tides_apsidal_motion_constant', dtype='float64', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_tides_gyration_radius(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('tides_gyration_radius', dtype='float64', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + #~ @legacy_function + #~ def get_tides_gyration_radius(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('tides_gyration_radius', dtype='float64', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_tides_viscous_time_scale(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('tides_viscous_time_scale', dtype='float64', direction=function.IN, unit=unit_t) + #~ function.result_type = 'int32' + #~ return function + #~ @legacy_function + #~ def get_tides_viscous_time_scale(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('tides_viscous_time_scale', dtype='float64', direction=function.OUT, unit=unit_t) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_tides_viscous_time_scale_prescription(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('tides_viscous_time_scale_prescription', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + #~ @legacy_function + #~ def get_tides_viscous_time_scale_prescription(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('tides_viscous_time_scale_prescription', dtype='int32', direction=function.OUT,unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_convective_envelope_mass(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('convective_envelope_mass', dtype='float64', direction=function.IN, unit=unit_m) + #~ function.result_type = 'int32' + #~ return function + #~ @legacy_function + #~ def get_convective_envelope_mass(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('convective_envelope_mass', dtype='float64', direction=function.OUT, unit=unit_m) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_convective_envelope_radius(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('convective_envelope_radius', dtype='float64', direction=function.IN, unit=unit_l) + #~ function.result_type = 'int32' + #~ return function + #~ @legacy_function + #~ def get_convective_envelope_radius(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('convective_envelope_radius', dtype='float64', direction=function.OUT, unit=unit_l) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_luminosity(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('luminosity', dtype='float64', direction=function.IN, unit=unit_lum) + #~ function.result_type = 'int32' + #~ return function + #~ @legacy_function + #~ def get_luminosity(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('luminosity', dtype='float64', direction=function.OUT, unit=unit_lum) + #~ function.result_type = 'int32' + #~ return function + + + + + + + #################### + ### root finding ### + #################### + + ### secular breakdown ### + #~ @legacy_function + #~ def set_check_for_secular_breakdown(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_secular_breakdown', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_check_for_secular_breakdown(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_secular_breakdown', dtype='bool', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + + ### dynamical instablity ### + #~ @legacy_function + #~ def set_check_for_dynamical_instability(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_dynamical_instability',dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_check_for_dynamical_instability(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_dynamical_instability',dtype='bool', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_dynamical_instability_criterion(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('dynamical_instability_criterion',dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_dynamical_instability_criterion(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('dynamical_instability_criterion',dtype='int32', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_dynamical_instability_central_particle(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('dynamical_instability_central_particle', dtype='int32', direction=function.IN, unit=LINK('particles')) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_dynamical_instability_central_particle(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('dynamical_instability_central_particle', dtype='int32', direction=function.OUT, unit=LINK('particles')) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_dynamical_instability_K_parameter(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='float64', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('dynamical_instability_K_parameter', dtype='float64', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_dynamical_instability_K_parameter(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='float64', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('dynamical_instability_K_parameter', dtype='float64', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + + ### physical collision / orbit crossing ### + #~ @legacy_function + #~ def set_check_for_physical_collision_or_orbit_crossing(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_physical_collision_or_orbit_crossing', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_check_for_physical_collision_or_orbit_crossing(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_physical_collision_or_orbit_crossing', dtype='bool', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + + ### minimum periapse distance reached ### + #~ @legacy_function + #~ def set_check_for_minimum_periapse_distance(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_minimum_periapse_distance', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_check_for_minimum_periapse_distance(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_minimum_periapse_distance', dtype='bool', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_check_for_minimum_periapse_distance_value(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_minimum_periapse_distance_value', dtype='float64', direction=function.IN, unit=unit_l) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_check_for_minimum_periapse_distance_value(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_minimum_periapse_distance_value', dtype='float64', direction=function.OUT, unit=unit_l) + #~ function.result_type = 'int32' + #~ return function + + + ### RLOF at pericentre ### + #~ @legacy_function + #~ def set_check_for_RLOF_at_pericentre(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_RLOF_at_pericentre', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_check_for_RLOF_at_pericentre(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_RLOF_at_pericentre', dtype='bool', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_check_for_RLOF_at_pericentre_use_sepinsky_fit(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_RLOF_at_pericentre_use_sepinsky_fit', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_check_for_RLOF_at_pericentre_use_sepinsky_fit(): + #~ function = LegacyFunctionSpecification() + #~ function.can_handle_array = True + #~ function.addParameter('index_of_the_particle', dtype='int32', direction=function.IN, unit=NO_UNIT) + #~ function.addParameter('check_for_RLOF_at_pericentre_use_sepinsky_fit', dtype='bool', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function ### retrieve root finding state ### @@ -1341,75 +1017,75 @@ def set_absolute_tolerance_eccentricity_vectors(): ### terms ### ############# - @legacy_function - def get_include_quadrupole_order_terms(): - function = LegacyFunctionSpecification() - function.addParameter('value', dtype='bool', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_include_quadrupole_order_terms(): - function = LegacyFunctionSpecification() - function.addParameter('value', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_include_octupole_order_binary_pair_terms(): - function = LegacyFunctionSpecification() - function.addParameter('value', dtype='bool', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_include_octupole_order_binary_pair_terms(): - function = LegacyFunctionSpecification() - function.addParameter('value', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_include_octupole_order_binary_triplet_terms(): - function = LegacyFunctionSpecification() - function.addParameter('value', dtype='bool', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_include_octupole_order_binary_triplet_terms(): - function = LegacyFunctionSpecification() - function.addParameter('value', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_include_hexadecupole_order_binary_pair_terms(): - function = LegacyFunctionSpecification() - function.addParameter('value', dtype='bool', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_include_hexadecupole_order_binary_pair_terms(): - function = LegacyFunctionSpecification() - function.addParameter('value', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def get_include_dotriacontupole_order_binary_pair_terms(): - function = LegacyFunctionSpecification() - function.addParameter('value', dtype='bool', direction=function.OUT, unit=NO_UNIT) - function.result_type = 'int32' - return function - - @legacy_function - def set_include_dotriacontupole_order_binary_pair_terms(): - function = LegacyFunctionSpecification() - function.addParameter('value', dtype='bool', direction=function.IN, unit=NO_UNIT) - function.result_type = 'int32' - return function + #~ @legacy_function + #~ def get_include_quadrupole_order_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.addParameter('value', dtype='bool', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_include_quadrupole_order_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.addParameter('value', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_include_octupole_order_binary_pair_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.addParameter('value', dtype='bool', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_include_octupole_order_binary_pair_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.addParameter('value', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_include_octupole_order_binary_triplet_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.addParameter('value', dtype='bool', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_include_octupole_order_binary_triplet_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.addParameter('value', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_include_hexadecupole_order_binary_pair_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.addParameter('value', dtype='bool', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_include_hexadecupole_order_binary_pair_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.addParameter('value', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def get_include_dotriacontupole_order_binary_pair_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.addParameter('value', dtype='bool', direction=function.OUT, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function + + #~ @legacy_function + #~ def set_include_dotriacontupole_order_binary_pair_terms(): + #~ function = LegacyFunctionSpecification() + #~ function.addParameter('value', dtype='bool', direction=function.IN, unit=NO_UNIT) + #~ function.result_type = 'int32' + #~ return function class SecularMultiple(InCodeComponentImplementation): diff --git a/src/amuse/community/secularmultiple/src/ODE_system.cpp b/src/amuse/community/secularmultiple/src/ODE_system.cpp deleted file mode 100644 index cd69c61012..0000000000 --- a/src/amuse/community/secularmultiple/src/ODE_system.cpp +++ /dev/null @@ -1,299 +0,0 @@ -#include "types.h" -#include "evolve.h" -#include "ODE_system.h" - -int compute_y_dot(realtype time, N_Vector y, N_Vector y_dot, void *data_) -{ - UserData data; - data = (UserData) data_; - ParticlesMap *particlesMap = data->particlesMap; - External_ParticlesMap *external_particlesMap = data->external_particlesMap; - - double start_time = data->start_time; - double delta_time = time - start_time; - - extract_ODE_variables(particlesMap, y, delta_time, true); // true: reset ODE quantities - - /**************************** - * compute right-hand sides * - * **************************/ - - double hamiltonian = 0.0; - ParticlesMapIterator it_p; - External_ParticlesMapIterator it_f; - std::vector::iterator it_parent_p,it_parent_q; - - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *p = (*it_p).second; - if (p->is_binary == 1) - { - - /* Newtonian gravitational point mass dynamics */ - - /* binary pairs */ - for (it_parent_p = p->parents.begin(); it_parent_p != p->parents.end(); it_parent_p++) - { - int i = std::distance(p->parents.begin(), it_parent_p); - Particle *P_q = (*particlesMap)[(*it_parent_p)]; - int connecting_child_in_parent_q = p->connecting_child_in_parents[i]; - hamiltonian += compute_EOM_binary_pairs(particlesMap,p->index,P_q->index,connecting_child_in_parent_q,false); - - /* binary triplets */ - for (it_parent_q = P_q->parents.begin(); it_parent_q != P_q->parents.end(); it_parent_q++) - { - int j = std::distance(P_q->parents.begin(), it_parent_q); - Particle *P_u = (*particlesMap)[(*it_parent_q)]; - int connecting_child_in_parent_u = P_q->connecting_child_in_parents[j]; - hamiltonian += compute_EOM_binary_triplets(particlesMap,p->index,P_q->index,P_u->index,connecting_child_in_parent_q,connecting_child_in_parent_u,false); - //printf("cross applied %d %d %d %d %d\n",P_p->index,P_q->index,P_u->index,connecting_child_in_parent_q,connecting_child_in_parent_u); - - } - } - - - /* perturbations by flybys */ - for (it_f = external_particlesMap->begin(); it_f != external_particlesMap->end(); it_f++) - { - External_Particle *f = (*it_f).second; - if (f->mode == 0) - { - hamiltonian += compute_EOM_binary_pairs_external_perturbation(particlesMap,external_particlesMap,p->index,f->index,time,false); - } - } - - /* Pairwise PN corrections */ - if (p->include_pairwise_1PN_terms == 1) - { - hamiltonian += compute_EOM_pairwise_1PN(particlesMap,p->index,false); - } - if (p->include_pairwise_25PN_terms == 1) - { - hamiltonian += compute_EOM_pairwise_25PN(particlesMap,p->index,false); - } - - /* tidal friction (ad hoc) */ - Particle *P_child1 = (*particlesMap)[p->child1]; - Particle *P_child2 = (*particlesMap)[p->child2]; - - if (P_child1->include_tidal_friction_terms == 1 || P_child1->include_tidal_bulges_precession_terms == 1 || P_child1->include_rotation_precession_terms == 1) - { - if (P_child1->tides_method == 0 || P_child1->tides_method == 1) - { - compute_EOM_equilibrium_tide_BO_full(particlesMap,p->index,P_child1->index,P_child2->index,P_child1->include_tidal_friction_terms,P_child1->include_tidal_bulges_precession_terms,P_child1->include_rotation_precession_terms,P_child1->minimum_eccentricity_for_tidal_precession,P_child1->tides_method); - } - else if (P_child1->tides_method == 2) - { - compute_EOM_equilibrium_tide(particlesMap,p->index,P_child1->index,P_child2->index,P_child1->include_tidal_friction_terms,P_child1->include_tidal_bulges_precession_terms,P_child1->include_rotation_precession_terms,P_child1->minimum_eccentricity_for_tidal_precession); - } - } - if (P_child2->include_tidal_friction_terms == 1 || P_child2->include_tidal_bulges_precession_terms == 1 || P_child2->include_rotation_precession_terms == 1) - { - if (P_child2->tides_method == 0 || P_child2->tides_method == 1) - { - compute_EOM_equilibrium_tide_BO_full(particlesMap,p->index,P_child2->index,P_child1->index,P_child2->include_tidal_friction_terms,P_child2->include_tidal_bulges_precession_terms,P_child2->include_rotation_precession_terms,P_child2->minimum_eccentricity_for_tidal_precession,P_child2->tides_method); - } - else if (P_child2->tides_method == 2) - { - compute_EOM_equilibrium_tide(particlesMap,p->index,P_child2->index,P_child1->index,P_child2->include_tidal_friction_terms,P_child2->include_tidal_bulges_precession_terms,P_child2->include_rotation_precession_terms,P_child2->minimum_eccentricity_for_tidal_precession); - } - - } - } - - } - - write_ODE_variables_dots(particlesMap,y_dot); - - data->hamiltonian = hamiltonian; - - return 0; -} - - -void extract_ODE_variables(ParticlesMap *particlesMap, N_Vector &y, double delta_time, bool reset_ODE_quantities) -{ - ParticlesMapIterator it_p; - int k=1; - int k_component; - -// double spin_vec[3],e_vec[3],h_vec[3]; -// double mass,radius; - - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - if (P_p->is_binary == 0) // particle is a body - { - for (k_component=0; k_component<3; k_component++) - { - P_p->spin_vec[k_component] = Ith(y,k + k_component); - } - P_p->mass = Ith(y,k + 2 + 1); - P_p->radius = Ith(y,k + 2 + 2); - - k=k+5; - } - if (P_p->is_binary == 1) // particle is a binary - { - for (k_component=0; k_component<3; k_component++) - { - P_p->e_vec[k_component] = Ith(y,k + k_component); - P_p->h_vec[k_component] = Ith(y,k + k_component + 3); - } - //printf("testttt %g %g %g\n",P_p->h_vec_x_dot_external,P_p->h_vec_y_dot_external,P_p->h_vec_z_dot_external); - k=k+6; - } - P_p->set_ODE_quantities(delta_time); - -// if (reset_ODE_quantities == true) -// { -// P_p->reset_ODE_quantities(); -// } -// printf("p %d a %g\n",P_p->index,P_p->a); -// printf("particle %d mass %g e_vec_x %g h_vec_x %g\n",P_p->index,P_p->mass,P_p->e_vec_x,P_p->h_vec_x); - } - set_binary_masses_from_body_masses(particlesMap); - -} - -void write_ODE_variables_dots(ParticlesMap *particlesMap, N_Vector &y_dot) -{ - ParticlesMapIterator it_p; - int k=1; - int k_component; - - double spin_vec[3],e_vec[3],h_vec[3]; - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - if (P_p->is_binary == 0) // particle is a body - { - for (k_component=0; k_component<3; k_component++) - { - Ith(y_dot,k + k_component) = P_p->dspin_vec_dt[k_component]; - } - - Ith(y_dot,k + 2 + 1) = P_p->dmass_dt; - Ith(y_dot,k + 2 + 2) = P_p->dradius_dt; - - k=k+5; - } - if (P_p->is_binary == 1) // particle is a binary - { - for (k_component=0; k_component<3; k_component++) - { - Ith(y_dot,k + k_component) = P_p->de_vec_dt[k_component]; - Ith(y_dot,k + k_component + 3) = P_p->dh_vec_dt[k_component]; - //printf("k %d out %g\n",k,Ith(y_dot,k + k_component)); - //printf("out %g\n",Ith(y_dot,k + k_component+3)); - - } - - //printf("P_p->child1_mass_dot_external %g P_p->child2_mass_dot_external %g\n",P_p->child1_mass_dot_external,P_p->child2_mass_dot_external); - //printf("out %g\n",2.0*dot3(P_p->h_vec_unit,P_p->dh_vec_dt)/norm3(P_p->h_vec) + (P_p->child1_mass_dot_external + P_p->child2_mass_dot_external)/P_p->child1_mass_plus_child2_mass \ - - 2.0*(P_p->child1_mass_dot_external/P_p->child1_mass + P_p->child2_mass_dot_external/P_p->child2_mass) ); - - - k=k+6; - } - } -} - -void set_initial_ODE_variables(ParticlesMap *particlesMap, N_Vector &y, N_Vector &y_abs_tol, double abs_tol_spin_vec, double abs_tol_e_vec, double abs_tol_h_vec) -{ - ParticlesMapIterator it_p; - int k=1; - int k_component; - - double spin_vec[3],e_vec[3],h_vec[3]; - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - if (P_p->is_binary == 0) // particle is a body - { - spin_vec[0] = P_p->spin_vec_x; - spin_vec[1] = P_p->spin_vec_y; - spin_vec[2] = P_p->spin_vec_z; - - for (k_component=0; k_component<3; k_component++) - { - Ith(y, k + k_component) = spin_vec[k_component]; - Ith(y_abs_tol, k + k_component) = abs_tol_spin_vec; - } - Ith(y, k + 2 + 1) = P_p->mass; - Ith(y, k + 2 + 2) = P_p->radius; - - Ith(y_abs_tol, k + 2 + 1) = relative_tolerance*P_p->mass; - Ith(y_abs_tol, k + 2 + 2) = relative_tolerance*P_p->radius; - - k=k+5; - } - if (P_p->is_binary == 1) // particle is a binary - { - e_vec[0] = P_p->e_vec_x; - e_vec[1] = P_p->e_vec_y; - e_vec[2] = P_p->e_vec_z; - h_vec[0] = P_p->h_vec_x; - h_vec[1] = P_p->h_vec_y; - h_vec[2] = P_p->h_vec_z; - double h = norm3(h_vec); - - for (k_component=0; k_component<3; k_component++) - { - Ith(y,k + k_component) = e_vec[k_component]; - Ith(y,k + k_component + 3) = h_vec[k_component]; - - Ith(y_abs_tol,k + k_component) = abs_tol_e_vec; -// Ith(y_abs_tol,k + k_component + 3) = abs_tol_h_vec; - Ith(y_abs_tol,k + k_component + 3) = relative_tolerance*h; - } - k=k+6; - } - } -} - -void extract_final_ODE_variables(ParticlesMap *particlesMap, N_Vector &y_out) -{ - ParticlesMapIterator it_p; - int k=1; - int k_component; - - double spin_vec[3],e_vec[3],h_vec[3]; - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - if (P_p->is_binary == 0) // particle is a body - { - for (k_component=0; k_component<3; k_component++) - { - spin_vec[k_component] = Ith(y_out,k + k_component); - } - P_p->spin_vec_x = spin_vec[0]; - P_p->spin_vec_y = spin_vec[1]; - P_p->spin_vec_z = spin_vec[2]; - - P_p->mass = Ith(y_out,k + 2 + 1); - P_p->radius = Ith(y_out,k + 2 + 2); - - k=k+5; - } - if (P_p->is_binary == 1) // particle is a binary - { - for (k_component=0; k_component<3; k_component++) - { - e_vec[k_component] = Ith(y_out,k + k_component); - h_vec[k_component] = Ith(y_out,k + k_component + 3); - } - - P_p->e_vec_x = e_vec[0]; - P_p->e_vec_y = e_vec[1]; - P_p->e_vec_z = e_vec[2]; - P_p->h_vec_x = h_vec[0]; - P_p->h_vec_y = h_vec[1]; - P_p->h_vec_z = h_vec[2]; - - k=k+6; - } - } -} diff --git a/src/amuse/community/secularmultiple/src/ODE_system.h b/src/amuse/community/secularmultiple/src/ODE_system.h deleted file mode 100644 index 45e5956dc2..0000000000 --- a/src/amuse/community/secularmultiple/src/ODE_system.h +++ /dev/null @@ -1,9 +0,0 @@ -#include "types.h" - -void extract_ODE_variables(ParticlesMap *particlesMap, N_Vector &y, double delta_time, bool reset_ODE_quantities); -void write_ODE_variables_dots(ParticlesMap *particlesMap, N_Vector &y_dot); - -int compute_y_dot(realtype time, N_Vector y, N_Vector y_dot, void *data_); - -void set_initial_ODE_variables(ParticlesMap *particlesMap, N_Vector &y, N_Vector &y_abs_tol,double abs_tol_spin_vec, double abs_tol_e_vec, double abs_tol_h_vec); -void extract_final_ODE_variables(ParticlesMap *particlesMap, N_Vector &y_out); diff --git a/src/amuse/community/secularmultiple/src/cvode/cvode.c b/src/amuse/community/secularmultiple/src/cvode/cvode.c deleted file mode 100755 index eee9919078..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/cvode.c +++ /dev/null @@ -1,4183 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.21 $ - * $Date: 2009/05/06 21:46:54 $ - * ----------------------------------------------------------------- - * Programmer(s): Scott D. Cohen, Alan C. Hindmarsh, Radu Serban, - * and Dan Shumaker @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the implementation file for the main CVODE integrator. - * It is independent of the CVODE linear solver in use. - * ----------------------------------------------------------------- - */ - -/*=================================================================*/ -/* Import Header Files */ -/*=================================================================*/ - -#include -#include -#include - -#include "cvode_impl.h" -#include "sundials_math.h" -#include "sundials_types.h" - -/*=================================================================*/ -/* Macros */ -/*=================================================================*/ - -/* Macro: loop */ -#define loop for(;;) - -/*=================================================================*/ -/* CVODE Private Constants */ -/*=================================================================*/ - -#define ZERO RCONST(0.0) /* real 0.0 */ -#define TINY RCONST(1.0e-10) /* small number */ -#define TENTH RCONST(0.1) /* real 0.1 */ -#define POINT2 RCONST(0.2) /* real 0.2 */ -#define FOURTH RCONST(0.25) /* real 0.25 */ -#define HALF RCONST(0.5) /* real 0.5 */ -#define ONE RCONST(1.0) /* real 1.0 */ -#define TWO RCONST(2.0) /* real 2.0 */ -#define THREE RCONST(3.0) /* real 3.0 */ -#define FOUR RCONST(4.0) /* real 4.0 */ -#define FIVE RCONST(5.0) /* real 5.0 */ -#define TWELVE RCONST(12.0) /* real 12.0 */ -#define HUN RCONST(100.0) /* real 100.0 */ - -/*=================================================================*/ -/* CVODE Routine-Specific Constants */ -/*=================================================================*/ - -/* - * Control constants for lower-level functions used by CVStep - * ---------------------------------------------------------- - * - * CVHin return values: - * CV_SUCCESS - * CV_RHSFUNC_FAIL - * CV_TOO_CLOSE - * - * CVStep control constants: - * DO_ERROR_TEST - * PREDICT_AGAIN - * - * CVStep return values: - * CV_SUCCESS, - * CV_LSETUP_FAIL, CV_LSOLVE_FAIL, - * CV_RHSFUNC_FAIL, CV_RTFUNC_FAIL - * CV_CONV_FAILURE, CV_ERR_FAILURE, - * CV_FIRST_RHSFUNC_ERR - * - * CVNls input nflag values: - * FIRST_CALL - * PREV_CONV_FAIL - * PREV_ERR_FAIL - * - * CVNls return values: - * CV_SUCCESS, - * CV_LSETUP_FAIL, CV_LSOLVE_FAIL, CV_RHSFUNC_FAIL, - * CONV_FAIL, RHSFUNC_RECVR - * - * CVNewtonIteration return values: - * CV_SUCCESS, - * CV_LSOLVE_FAIL, CV_RHSFUNC_FAIL - * CONV_FAIL, RHSFUNC_RECVR, - * TRY_AGAIN - * - */ - -#define DO_ERROR_TEST +2 -#define PREDICT_AGAIN +3 - -#define CONV_FAIL +4 -#define TRY_AGAIN +5 - -#define FIRST_CALL +6 -#define PREV_CONV_FAIL +7 -#define PREV_ERR_FAIL +8 - -#define RHSFUNC_RECVR +9 - -/* - * Control constants for lower-level rootfinding functions - * ------------------------------------------------------- - * - * CVRcheck1 return values: - * CV_SUCCESS, - * CV_RTFUNC_FAIL, - * CVRcheck2 return values: - * CV_SUCCESS - * CV_RTFUNC_FAIL, - * CLOSERT - * RTFOUND - * CVRcheck3 return values: - * CV_SUCCESS - * CV_RTFUNC_FAIL, - * RTFOUND - * CVRootfind return values: - * CV_SUCCESS - * CV_RTFUNC_FAIL, - * RTFOUND - */ - -#define RTFOUND +1 -#define CLOSERT +3 - -/* - * Control constants for tolerances - * -------------------------------- - */ - -#define CV_NN 0 -#define CV_SS 1 -#define CV_SV 2 -#define CV_WF 3 - -/* - * Algorithmic constants - * --------------------- - * - * CVodeGetDky and CVStep - * - * FUZZ_FACTOR - * - * CVHin - * - * HLB_FACTOR - * HUB_FACTOR - * H_BIAS - * MAX_ITERS - * - * CVodeCreate - * - * CORTES - * - * CVStep - * - * THRESH - * ETAMX1 - * ETAMX2 - * ETAMX3 - * ETAMXF - * ETAMIN - * ETACF - * ADDON - * BIAS1 - * BIAS2 - * BIAS3 - * ONEPSM - * - * SMALL_NST nst > SMALL_NST => use ETAMX3 - * MXNCF max no. of convergence failures during one step try - * MXNEF max no. of error test failures during one step try - * MXNEF1 max no. of error test failures before forcing a reduction of order - * SMALL_NEF if an error failure occurs and SMALL_NEF <= nef <= MXNEF1, then - * reset eta = MIN(eta, ETAMXF) - * LONG_WAIT number of steps to wait before considering an order change when - * q==1 and MXNEF1 error test failures have occurred - * - * CVNls - * - * NLS_MAXCOR maximum no. of corrector iterations for the nonlinear solver - * CRDOWN constant used in the estimation of the convergence rate (crate) - * of the iterates for the nonlinear equation - * DGMAX iter == CV_NEWTON, |gamma/gammap-1| > DGMAX => call lsetup - * RDIV declare divergence if ratio del/delp > RDIV - * MSBP max no. of steps between lsetup calls - * - */ - - -#define FUZZ_FACTOR RCONST(100.0) - -#define HLB_FACTOR RCONST(100.0) -#define HUB_FACTOR RCONST(0.1) -#define H_BIAS HALF -#define MAX_ITERS 4 - -#define CORTES RCONST(0.1) - -#define THRESH RCONST(1.5) -#define ETAMX1 RCONST(10000.0) -#define ETAMX2 RCONST(10.0) -#define ETAMX3 RCONST(10.0) -#define ETAMXF RCONST(0.2) -#define ETAMIN RCONST(0.1) -#define ETACF RCONST(0.25) -#define ADDON RCONST(0.000001) -#define BIAS1 RCONST(6.0) -#define BIAS2 RCONST(6.0) -#define BIAS3 RCONST(10.0) -#define ONEPSM RCONST(1.000001) - -#define SMALL_NST 10 -#define MXNCF 10 -#define MXNEF 7 -#define MXNEF1 3 -#define SMALL_NEF 2 -#define LONG_WAIT 10 - -#define NLS_MAXCOR 3 -#define CRDOWN RCONST(0.3) -#define DGMAX RCONST(0.3) - -#define RDIV TWO -#define MSBP 20 - -/*=================================================================*/ -/* Private Helper Functions Prototypes */ -/*=================================================================*/ - -static booleantype CVCheckNvector(N_Vector tmpl); - -static int CVInitialSetup(CVodeMem cv_mem); - -static booleantype CVAllocVectors(CVodeMem cv_mem, N_Vector tmpl); -static void CVFreeVectors(CVodeMem cv_mem); - -static int CVEwtSetSS(CVodeMem cv_mem, N_Vector ycur, N_Vector weight); -static int CVEwtSetSV(CVodeMem cv_mem, N_Vector ycur, N_Vector weight); - -static int CVHin(CVodeMem cv_mem, realtype tout); -static realtype CVUpperBoundH0(CVodeMem cv_mem, realtype tdist); -static int CVYddNorm(CVodeMem cv_mem, realtype hg, realtype *yddnrm); - -static int CVStep(CVodeMem cv_mem); - -static int CVsldet(CVodeMem cv_mem); - -static void CVAdjustParams(CVodeMem cv_mem); -static void CVAdjustOrder(CVodeMem cv_mem, int deltaq); -static void CVAdjustAdams(CVodeMem cv_mem, int deltaq); -static void CVAdjustBDF(CVodeMem cv_mem, int deltaq); -static void CVIncreaseBDF(CVodeMem cv_mem); -static void CVDecreaseBDF(CVodeMem cv_mem); - -static void CVRescale(CVodeMem cv_mem); - -static void CVPredict(CVodeMem cv_mem); - -static void CVSet(CVodeMem cv_mem); -static void CVSetAdams(CVodeMem cv_mem); -static realtype CVAdamsStart(CVodeMem cv_mem, realtype m[]); -static void CVAdamsFinish(CVodeMem cv_mem, realtype m[], realtype M[], realtype hsum); -static realtype CVAltSum(int iend, realtype a[], int k); -static void CVSetBDF(CVodeMem cv_mem); -static void CVSetTqBDF(CVodeMem cv_mem, realtype hsum, realtype alpha0, - realtype alpha0_hat, realtype xi_inv, realtype xistar_inv); - -static int CVNls(CVodeMem cv_mem, int nflag); -static int CVNlsFunctional(CVodeMem cv_mem); -static int CVNlsNewton(CVodeMem cv_mem, int nflag); -static int CVNewtonIteration(CVodeMem cv_mem); - -static int CVHandleNFlag(CVodeMem cv_mem, int *nflagPtr, realtype saved_t, - int *ncfPtr); - -static void CVRestore(CVodeMem cv_mem, realtype saved_t); - -static int CVDoErrorTest(CVodeMem cv_mem, int *nflagPtr, - realtype saved_t, int *nefPtr, realtype *dsmPtr); - -static void CVCompleteStep(CVodeMem cv_mem); - -static void CVPrepareNextStep(CVodeMem cv_mem, realtype dsm); -static void CVSetEta(CVodeMem cv_mem); -static realtype CVComputeEtaqm1(CVodeMem cv_mem); -static realtype CVComputeEtaqp1(CVodeMem cv_mem); -static void CVChooseEta(CVodeMem cv_mem); -static void CVBDFStab(CVodeMem cv_mem); - -static int CVHandleFailure(CVodeMem cv_mem,int flag); - -static int CVRcheck1(CVodeMem cv_mem); -static int CVRcheck2(CVodeMem cv_mem); -static int CVRcheck3(CVodeMem cv_mem); -static int CVRootfind(CVodeMem cv_mem); - -/* - * ================================================================= - * EXPORTED FUNCTIONS IMPLEMENTATION - * ================================================================= - */ - -/* - * CVodeCreate - * - * CVodeCreate creates an internal memory block for a problem to - * be solved by CVODE. - * If successful, CVodeCreate returns a pointer to the problem memory. - * This pointer should be passed to CVodeInit. - * If an initialization error occurs, CVodeCreate prints an error - * message to standard err and returns NULL. - */ - -void *CVodeCreate(int lmm, int iter) -{ - int maxord; - CVodeMem cv_mem; - - /* Test inputs */ - - if ((lmm != CV_ADAMS) && (lmm != CV_BDF)) { - CVProcessError(NULL, 0, "CVODE", "CVodeCreate", MSGCV_BAD_LMM); - return(NULL); - } - - if ((iter != CV_FUNCTIONAL) && (iter != CV_NEWTON)) { - CVProcessError(NULL, 0, "CVODE", "CVodeCreate", MSGCV_BAD_ITER); - return(NULL); - } - - cv_mem = NULL; - cv_mem = (CVodeMem) malloc(sizeof(struct CVodeMemRec)); - if (cv_mem == NULL) { - CVProcessError(NULL, 0, "CVODE", "CVodeCreate", MSGCV_CVMEM_FAIL); - return(NULL); - } - - maxord = (lmm == CV_ADAMS) ? ADAMS_Q_MAX : BDF_Q_MAX; - - /* copy input parameters into cv_mem */ - cv_mem->cv_lmm = lmm; - cv_mem->cv_iter = iter; - - /* Set uround */ - cv_mem->cv_uround = UNIT_ROUNDOFF; - - /* Set default values for integrator optional inputs */ - cv_mem->cv_f = NULL; - cv_mem->cv_user_data = NULL; - cv_mem->cv_itol = CV_NN; - cv_mem->cv_user_efun = FALSE; - cv_mem->cv_efun = NULL; - cv_mem->cv_e_data = NULL; - cv_mem->cv_ehfun = CVErrHandler; - cv_mem->cv_eh_data = cv_mem; - cv_mem->cv_errfp = stderr; - cv_mem->cv_qmax = maxord; - cv_mem->cv_mxstep = MXSTEP_DEFAULT; - cv_mem->cv_mxhnil = MXHNIL_DEFAULT; - cv_mem->cv_sldeton = FALSE; - cv_mem->cv_hin = ZERO; - cv_mem->cv_hmin = HMIN_DEFAULT; - cv_mem->cv_hmax_inv = HMAX_INV_DEFAULT; - cv_mem->cv_tstopset = FALSE; - cv_mem->cv_maxcor = NLS_MAXCOR; - cv_mem->cv_maxnef = MXNEF; - cv_mem->cv_maxncf = MXNCF; - cv_mem->cv_nlscoef = CORTES; - - /* Initialize root finding variables */ - - cv_mem->cv_glo = NULL; - cv_mem->cv_ghi = NULL; - cv_mem->cv_grout = NULL; - cv_mem->cv_iroots = NULL; - cv_mem->cv_rootdir = NULL; - cv_mem->cv_gfun = NULL; - cv_mem->cv_nrtfn = 0; - cv_mem->cv_gactive = NULL; - cv_mem->cv_mxgnull = 1; - - /* Set the saved value qmax_alloc */ - - cv_mem->cv_qmax_alloc = maxord; - - /* Initialize lrw and liw */ - - cv_mem->cv_lrw = 58 + 2*L_MAX + NUM_TESTS; - cv_mem->cv_liw = 40; - - /* No mallocs have been done yet */ - - cv_mem->cv_VabstolMallocDone = FALSE; - cv_mem->cv_MallocDone = FALSE; - - /* Return pointer to CVODE memory block */ - - return((void *)cv_mem); -} - -/*-----------------------------------------------------------------*/ - -#define iter (cv_mem->cv_iter) -#define lmm (cv_mem->cv_lmm) -#define lrw (cv_mem->cv_lrw) -#define liw (cv_mem->cv_liw) - -/*-----------------------------------------------------------------*/ - -/* - * CVodeInit - * - * CVodeInit allocates and initializes memory for a problem. All - * problem inputs are checked for errors. If any error occurs during - * initialization, it is reported to the file whose file pointer is - * errfp and an error flag is returned. Otherwise, it returns CV_SUCCESS - */ - -int CVodeInit(void *cvode_mem, CVRhsFn f, realtype t0, N_Vector y0) -{ - CVodeMem cv_mem; - booleantype nvectorOK, allocOK; - long int lrw1, liw1; - int i,k; - - /* Check cvode_mem */ - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeInit", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - /* Check for legal input parameters */ - - if (y0==NULL) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeInit", MSGCV_NULL_Y0); - return(CV_ILL_INPUT); - } - - if (f == NULL) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeInit", MSGCV_NULL_F); - return(CV_ILL_INPUT); - } - - /* Test if all required vector operations are implemented */ - - nvectorOK = CVCheckNvector(y0); - if(!nvectorOK) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeInit", MSGCV_BAD_NVECTOR); - return(CV_ILL_INPUT); - } - - /* Set space requirements for one N_Vector */ - - if (y0->ops->nvspace != NULL) { - N_VSpace(y0, &lrw1, &liw1); - } else { - lrw1 = 0; - liw1 = 0; - } - cv_mem->cv_lrw1 = lrw1; - cv_mem->cv_liw1 = liw1; - - /* Allocate the vectors (using y0 as a template) */ - - allocOK = CVAllocVectors(cv_mem, y0); - if (!allocOK) { - CVProcessError(cv_mem, CV_MEM_FAIL, "CVODE", "CVodeInit", MSGCV_MEM_FAIL); - return(CV_MEM_FAIL); - } - - /* All error checking is complete at this point */ - - /* Copy the input parameters into CVODE state */ - - cv_mem->cv_f = f; - cv_mem->cv_tn = t0; - - /* Set step parameters */ - - cv_mem->cv_q = 1; - cv_mem->cv_L = 2; - cv_mem->cv_qwait = cv_mem->cv_L; - cv_mem->cv_etamax = ETAMX1; - - cv_mem->cv_qu = 0; - cv_mem->cv_hu = ZERO; - cv_mem->cv_tolsf = ONE; - - /* Set the linear solver addresses to NULL. - (We check != NULL later, in CVode, if using CV_NEWTON.) */ - - cv_mem->cv_linit = NULL; - cv_mem->cv_lsetup = NULL; - cv_mem->cv_lsolve = NULL; - cv_mem->cv_lfree = NULL; - cv_mem->cv_lmem = NULL; - - /* Initialize zn[0] in the history array */ - - N_VScale(ONE, y0, cv_mem->cv_zn[0]); - - /* Initialize all the counters */ - - cv_mem->cv_nst = 0; - cv_mem->cv_nfe = 0; - cv_mem->cv_ncfn = 0; - cv_mem->cv_netf = 0; - cv_mem->cv_nni = 0; - cv_mem->cv_nsetups = 0; - cv_mem->cv_nhnil = 0; - cv_mem->cv_nstlp = 0; - cv_mem->cv_nscon = 0; - cv_mem->cv_nge = 0; - - cv_mem->cv_irfnd = 0; - - /* Initialize other integrator optional outputs */ - - cv_mem->cv_h0u = ZERO; - cv_mem->cv_next_h = ZERO; - cv_mem->cv_next_q = 0; - - /* Initialize Stablilty Limit Detection data */ - /* NOTE: We do this even if stab lim det was not - turned on yet. This way, the user can turn it - on at any time */ - - cv_mem->cv_nor = 0; - for (i = 1; i <= 5; i++) - for (k = 1; k <= 3; k++) - cv_mem->cv_ssdat[i-1][k-1] = ZERO; - - /* Problem has been successfully initialized */ - - cv_mem->cv_MallocDone = TRUE; - - return(CV_SUCCESS); -} - -/*-----------------------------------------------------------------*/ - -#define lrw1 (cv_mem->cv_lrw1) -#define liw1 (cv_mem->cv_liw1) - -/*-----------------------------------------------------------------*/ - -/* - * CVodeReInit - * - * CVodeReInit re-initializes CVODE's memory for a problem, assuming - * it has already been allocated in a prior CVodeInit call. - * All problem specification inputs are checked for errors. - * If any error occurs during initialization, it is reported to the - * file whose file pointer is errfp. - * The return value is CV_SUCCESS = 0 if no errors occurred, or - * a negative value otherwise. - */ - -int CVodeReInit(void *cvode_mem, realtype t0, N_Vector y0) -{ - CVodeMem cv_mem; - int i,k; - - /* Check cvode_mem */ - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeReInit", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - /* Check if cvode_mem was allocated */ - - if (cv_mem->cv_MallocDone == FALSE) { - CVProcessError(cv_mem, CV_NO_MALLOC, "CVODE", "CVodeReInit", MSGCV_NO_MALLOC); - return(CV_NO_MALLOC); - } - - /* Check for legal input parameters */ - - if (y0 == NULL) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeReInit", MSGCV_NULL_Y0); - return(CV_ILL_INPUT); - } - - /* Copy the input parameters into CVODE state */ - - cv_mem->cv_tn = t0; - - /* Set step parameters */ - - cv_mem->cv_q = 1; - cv_mem->cv_L = 2; - cv_mem->cv_qwait = cv_mem->cv_L; - cv_mem->cv_etamax = ETAMX1; - - cv_mem->cv_qu = 0; - cv_mem->cv_hu = ZERO; - cv_mem->cv_tolsf = ONE; - - /* Initialize zn[0] in the history array */ - - N_VScale(ONE, y0, cv_mem->cv_zn[0]); - - /* Initialize all the counters */ - - cv_mem->cv_nst = 0; - cv_mem->cv_nfe = 0; - cv_mem->cv_ncfn = 0; - cv_mem->cv_netf = 0; - cv_mem->cv_nni = 0; - cv_mem->cv_nsetups = 0; - cv_mem->cv_nhnil = 0; - cv_mem->cv_nstlp = 0; - cv_mem->cv_nscon = 0; - cv_mem->cv_nge = 0; - - cv_mem->cv_irfnd = 0; - - /* Initialize other integrator optional outputs */ - - cv_mem->cv_h0u = ZERO; - cv_mem->cv_next_h = ZERO; - cv_mem->cv_next_q = 0; - - /* Initialize Stablilty Limit Detection data */ - - cv_mem->cv_nor = 0; - for (i = 1; i <= 5; i++) - for (k = 1; k <= 3; k++) - cv_mem->cv_ssdat[i-1][k-1] = ZERO; - - /* Problem has been successfully re-initialized */ - - return(CV_SUCCESS); -} - -/*-----------------------------------------------------------------*/ - -/* - * CVodeSStolerances - * CVodeSVtolerances - * CVodeWFtolerances - * - * These functions specify the integration tolerances. One of them - * MUST be called before the first call to CVode. - * - * CVodeSStolerances specifies scalar relative and absolute tolerances. - * CVodeSVtolerances specifies scalar relative tolerance and a vector - * absolute tolerance (a potentially different absolute tolerance - * for each vector component). - * CVodeWFtolerances specifies a user-provides function (of type CVEwtFn) - * which will be called to set the error weight vector. - */ - -int CVodeSStolerances(void *cvode_mem, realtype reltol, realtype abstol) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSStolerances", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - if (cv_mem->cv_MallocDone == FALSE) { - CVProcessError(cv_mem, CV_NO_MALLOC, "CVODE", "CVodeSStolerances", MSGCV_NO_MALLOC); - return(CV_NO_MALLOC); - } - - /* Check inputs */ - - if (reltol < ZERO) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSStolerances", MSGCV_BAD_RELTOL); - return(CV_ILL_INPUT); - } - - if (abstol < ZERO) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSStolerances", MSGCV_BAD_ABSTOL); - return(CV_ILL_INPUT); - } - - /* Copy tolerances into memory */ - - cv_mem->cv_reltol = reltol; - cv_mem->cv_Sabstol = abstol; - - cv_mem->cv_itol = CV_SS; - - cv_mem->cv_user_efun = FALSE; - cv_mem->cv_efun = CVEwtSet; - cv_mem->cv_e_data = NULL; /* will be set to cvode_mem in InitialSetup */ - - return(CV_SUCCESS); -} - - -int CVodeSVtolerances(void *cvode_mem, realtype reltol, N_Vector abstol) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSVtolerances", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - if (cv_mem->cv_MallocDone == FALSE) { - CVProcessError(cv_mem, CV_NO_MALLOC, "CVODE", "CVodeSVtolerances", MSGCV_NO_MALLOC); - return(CV_NO_MALLOC); - } - - /* Check inputs */ - - if (reltol < ZERO) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSVtolerances", MSGCV_BAD_RELTOL); - return(CV_ILL_INPUT); - } - - if (N_VMin(abstol) < ZERO) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSVtolerances", MSGCV_BAD_ABSTOL); - return(CV_ILL_INPUT); - } - - /* Copy tolerances into memory */ - - if ( !(cv_mem->cv_VabstolMallocDone) ) { - cv_mem->cv_Vabstol = N_VClone(cv_mem->cv_ewt); - lrw += lrw1; - liw += liw1; - cv_mem->cv_VabstolMallocDone = TRUE; - } - - cv_mem->cv_reltol = reltol; - N_VScale(ONE, abstol, cv_mem->cv_Vabstol); - - cv_mem->cv_itol = CV_SV; - - cv_mem->cv_user_efun = FALSE; - cv_mem->cv_efun = CVEwtSet; - cv_mem->cv_e_data = NULL; /* will be set to cvode_mem in InitialSetup */ - - return(CV_SUCCESS); -} - - -int CVodeWFtolerances(void *cvode_mem, CVEwtFn efun) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeWFtolerances", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - if (cv_mem->cv_MallocDone == FALSE) { - CVProcessError(cv_mem, CV_NO_MALLOC, "CVODE", "CVodeWFtolerances", MSGCV_NO_MALLOC); - return(CV_NO_MALLOC); - } - - cv_mem->cv_itol = CV_WF; - - cv_mem->cv_user_efun = TRUE; - cv_mem->cv_efun = efun; - cv_mem->cv_e_data = NULL; /* will be set to user_data in InitialSetup */ - - return(CV_SUCCESS); -} - -/*-----------------------------------------------------------------*/ - -#define gfun (cv_mem->cv_gfun) -#define glo (cv_mem->cv_glo) -#define ghi (cv_mem->cv_ghi) -#define grout (cv_mem->cv_grout) -#define iroots (cv_mem->cv_iroots) -#define rootdir (cv_mem->cv_rootdir) -#define gactive (cv_mem->cv_gactive) - -/*-----------------------------------------------------------------*/ - -/* - * CVodeRootInit - * - * CVodeRootInit initializes a rootfinding problem to be solved - * during the integration of the ODE system. It loads the root - * function pointer and the number of root functions, and allocates - * workspace memory. The return value is CV_SUCCESS = 0 if no errors - * occurred, or a negative value otherwise. - */ - -int CVodeRootInit(void *cvode_mem, int nrtfn, CVRootFn g) -{ - CVodeMem cv_mem; - int i, nrt; - - /* Check cvode_mem pointer */ - if (cvode_mem == NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeRootInit", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - nrt = (nrtfn < 0) ? 0 : nrtfn; - - /* If rerunning CVodeRootInit() with a different number of root - functions (changing number of gfun components), then free - currently held memory resources */ - if ((nrt != cv_mem->cv_nrtfn) && (cv_mem->cv_nrtfn > 0)) { - free(glo); glo = NULL; - free(ghi); ghi = NULL; - free(grout); grout = NULL; - free(iroots); iroots = NULL; - free(rootdir); rootdir = NULL; - free(gactive); gactive = NULL; - - lrw -= 3 * (cv_mem->cv_nrtfn); - liw -= 3 * (cv_mem->cv_nrtfn); - } - - /* If CVodeRootInit() was called with nrtfn == 0, then set cv_nrtfn to - zero and cv_gfun to NULL before returning */ - if (nrt == 0) { - cv_mem->cv_nrtfn = nrt; - gfun = NULL; - return(CV_SUCCESS); - } - - /* If rerunning CVodeRootInit() with the same number of root functions - (not changing number of gfun components), then check if the root - function argument has changed */ - /* If g != NULL then return as currently reserved memory resources - will suffice */ - if (nrt == cv_mem->cv_nrtfn) { - if (g != gfun) { - if (g == NULL) { - free(glo); glo = NULL; - free(ghi); ghi = NULL; - free(grout); grout = NULL; - free(iroots); iroots = NULL; - free(rootdir); rootdir = NULL; - free(gactive); gactive = NULL; - - lrw -= 3*nrt; - liw -= 3*nrt; - - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeRootInit", MSGCV_NULL_G); - return(CV_ILL_INPUT); - } - else { - gfun = g; - return(CV_SUCCESS); - } - } - else return(CV_SUCCESS); - } - - /* Set variable values in CVode memory block */ - cv_mem->cv_nrtfn = nrt; - if (g == NULL) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeRootInit", MSGCV_NULL_G); - return(CV_ILL_INPUT); - } - else gfun = g; - - /* Allocate necessary memory and return */ - glo = NULL; - glo = (realtype *) malloc(nrt*sizeof(realtype)); - if (glo == NULL) { - CVProcessError(cv_mem, CV_MEM_FAIL, "CVODE", "CVodeRootInit", MSGCV_MEM_FAIL); - return(CV_MEM_FAIL); - } - - ghi = NULL; - ghi = (realtype *) malloc(nrt*sizeof(realtype)); - if (ghi == NULL) { - free(glo); glo = NULL; - CVProcessError(cv_mem, CV_MEM_FAIL, "CVODE", "CVodeRootInit", MSGCV_MEM_FAIL); - return(CV_MEM_FAIL); - } - - grout = NULL; - grout = (realtype *) malloc(nrt*sizeof(realtype)); - if (grout == NULL) { - free(glo); glo = NULL; - free(ghi); ghi = NULL; - CVProcessError(cv_mem, CV_MEM_FAIL, "CVODE", "CVodeRootInit", MSGCV_MEM_FAIL); - return(CV_MEM_FAIL); - } - - iroots = NULL; - iroots = (int *) malloc(nrt*sizeof(int)); - if (iroots == NULL) { - free(glo); glo = NULL; - free(ghi); ghi = NULL; - free(grout); grout = NULL; - CVProcessError(cv_mem, CV_MEM_FAIL, "CVODE", "CVodeRootInit", MSGCV_MEM_FAIL); - return(CV_MEM_FAIL); - } - - rootdir = NULL; - rootdir = (int *) malloc(nrt*sizeof(int)); - if (rootdir == NULL) { - free(glo); glo = NULL; - free(ghi); ghi = NULL; - free(grout); grout = NULL; - free(iroots); iroots = NULL; - CVProcessError(cv_mem, CV_MEM_FAIL, "CVODE", "CVodeRootInit", MSGCV_MEM_FAIL); - return(CV_MEM_FAIL); - } - - gactive = NULL; - gactive = (booleantype *) malloc(nrt*sizeof(booleantype)); - if (gactive == NULL) { - free(glo); glo = NULL; - free(ghi); ghi = NULL; - free(grout); grout = NULL; - free(iroots); iroots = NULL; - free(rootdir); rootdir = NULL; - CVProcessError(cv_mem, CV_MEM_FAIL, "CVODES", "CVodeRootInit", MSGCV_MEM_FAIL); - return(CV_MEM_FAIL); - } - - /* Set default values for rootdir (both directions) */ - for(i=0; icv_f) -#define user_data (cv_mem->cv_user_data) -#define efun (cv_mem->cv_efun) -#define e_data (cv_mem->cv_e_data) -#define qmax (cv_mem->cv_qmax) -#define mxstep (cv_mem->cv_mxstep) -#define mxhnil (cv_mem->cv_mxhnil) -#define sldeton (cv_mem->cv_sldeton) -#define hin (cv_mem->cv_hin) -#define hmin (cv_mem->cv_hmin) -#define hmax_inv (cv_mem->cv_hmax_inv) -#define tstop (cv_mem->cv_tstop) -#define tstopset (cv_mem->cv_tstopset) -#define maxnef (cv_mem->cv_maxnef) -#define maxncf (cv_mem->cv_maxncf) -#define maxcor (cv_mem->cv_maxcor) -#define nlscoef (cv_mem->cv_nlscoef) -#define itol (cv_mem->cv_itol) -#define reltol (cv_mem->cv_reltol) -#define Sabstol (cv_mem->cv_Sabstol) -#define Vabstol (cv_mem->cv_Vabstol) - -#define uround (cv_mem->cv_uround) -#define zn (cv_mem->cv_zn) -#define ewt (cv_mem->cv_ewt) -#define y (cv_mem->cv_y) -#define acor (cv_mem->cv_acor) -#define tempv (cv_mem->cv_tempv) -#define ftemp (cv_mem->cv_ftemp) -#define q (cv_mem->cv_q) -#define qprime (cv_mem->cv_qprime) -#define next_q (cv_mem->cv_next_q) -#define qwait (cv_mem->cv_qwait) -#define L (cv_mem->cv_L) -#define h (cv_mem->cv_h) -#define hprime (cv_mem->cv_hprime) -#define next_h (cv_mem->cv_next_h) -#define eta (cv_mem->cv_eta) -#define etaqm1 (cv_mem->cv_etaqm1) -#define etaq (cv_mem->cv_etaq) -#define etaqp1 (cv_mem->cv_etaqp1) -#define nscon (cv_mem->cv_nscon) -#define hscale (cv_mem->cv_hscale) -#define tn (cv_mem->cv_tn) -#define tau (cv_mem->cv_tau) -#define tq (cv_mem->cv_tq) -#define l (cv_mem->cv_l) -#define rl1 (cv_mem->cv_rl1) -#define gamma (cv_mem->cv_gamma) -#define gammap (cv_mem->cv_gammap) -#define gamrat (cv_mem->cv_gamrat) -#define crate (cv_mem->cv_crate) -#define acnrm (cv_mem->cv_acnrm) -#define mnewt (cv_mem->cv_mnewt) -#define etamax (cv_mem->cv_etamax) -#define nst (cv_mem->cv_nst) -#define nfe (cv_mem->cv_nfe) -#define ncfn (cv_mem->cv_ncfn) -#define netf (cv_mem->cv_netf) -#define nni (cv_mem->cv_nni) -#define nsetups (cv_mem->cv_nsetups) -#define nhnil (cv_mem->cv_nhnil) -#define linit (cv_mem->cv_linit) -#define lsetup (cv_mem->cv_lsetup) -#define lsolve (cv_mem->cv_lsolve) -#define lfree (cv_mem->cv_lfree) -#define lmem (cv_mem->cv_lmem) -#define qu (cv_mem->cv_qu) -#define nstlp (cv_mem->cv_nstlp) -#define h0u (cv_mem->cv_h0u) -#define hu (cv_mem->cv_hu) -#define saved_tq5 (cv_mem->cv_saved_tq5) -#define indx_acor (cv_mem->cv_indx_acor) -#define jcur (cv_mem->cv_jcur) -#define tolsf (cv_mem->cv_tolsf) -#define setupNonNull (cv_mem->cv_setupNonNull) -#define nor (cv_mem->cv_nor) -#define ssdat (cv_mem->cv_ssdat) - -#define nrtfn (cv_mem->cv_nrtfn) -#define tlo (cv_mem->cv_tlo) -#define thi (cv_mem->cv_thi) -#define tretlast (cv_mem->cv_tretlast) -#define toutc (cv_mem->cv_toutc) -#define trout (cv_mem->cv_trout) -#define ttol (cv_mem->cv_ttol) -#define taskc (cv_mem->cv_taskc) -#define irfnd (cv_mem->cv_irfnd) -#define nge (cv_mem->cv_nge) - - -/*-----------------------------------------------------------------*/ - -/* - * CVode - * - * This routine is the main driver of the CVODE package. - * - * It integrates over a time interval defined by the user, by calling - * CVStep to do internal time steps. - * - * The first time that CVode is called for a successfully initialized - * problem, it computes a tentative initial step size h. - * - * CVode supports two modes, specified by itask: CV_NORMAL, CV_ONE_STEP. - * In the CV_NORMAL mode, the solver steps until it reaches or passes tout - * and then interpolates to obtain y(tout). - * In the CV_ONE_STEP mode, it takes one internal step and returns. - */ - -int CVode(void *cvode_mem, realtype tout, N_Vector yout, - realtype *tret, int itask) -{ - CVodeMem cv_mem; - long int nstloc; - int retval, hflag, kflag, istate, ir, ier, irfndp; - int ewtsetOK; - realtype troundoff, tout_hin, rh, nrm; - booleantype inactive_roots; - - /* - * ------------------------------------- - * 1. Check and process inputs - * ------------------------------------- - */ - - /* Check if cvode_mem exists */ - if (cvode_mem == NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVode", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - /* Check if cvode_mem was allocated */ - if (cv_mem->cv_MallocDone == FALSE) { - CVProcessError(cv_mem, CV_NO_MALLOC, "CVODE", "CVode", MSGCV_NO_MALLOC); - return(CV_NO_MALLOC); - } - - /* Check for yout != NULL */ - if ((y = yout) == NULL) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_YOUT_NULL); - return(CV_ILL_INPUT); - } - - /* Check for tret != NULL */ - if (tret == NULL) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_TRET_NULL); - return(CV_ILL_INPUT); - } - - /* Check for valid itask */ - if ( (itask != CV_NORMAL) && (itask != CV_ONE_STEP) ) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_BAD_ITASK); - return(CV_ILL_INPUT); - } - - if (itask == CV_NORMAL) toutc = tout; - taskc = itask; - - /* - * ---------------------------------------- - * 2. Initializations performed only at - * the first step (nst=0): - * - initial setup - * - initialize Nordsieck history array - * - compute initial step size - * - check for approach to tstop - * - check for approach to a root - * ---------------------------------------- - */ - - if (nst == 0) { - - ier = CVInitialSetup(cv_mem); - if (ier!= CV_SUCCESS) return(ier); - - /* Call f at (t0,y0), set zn[1] = y'(t0), - set initial h (from H0 or CVHin), and scale zn[1] by h. - Also check for zeros of root function g at and near t0. */ - - retval = f(tn, zn[0], zn[1], user_data); - nfe++; - if (retval < 0) { - CVProcessError(cv_mem, CV_RHSFUNC_FAIL, "CVODE", "CVode", MSGCV_RHSFUNC_FAILED, tn); - return(CV_RHSFUNC_FAIL); - } - if (retval > 0) { - CVProcessError(cv_mem, CV_FIRST_RHSFUNC_ERR, "CVODE", "CVode", MSGCV_RHSFUNC_FIRST); - return(CV_FIRST_RHSFUNC_ERR); - } - - /* Set initial h (from H0 or CVHin). */ - - h = hin; - if ( (h != ZERO) && ((tout-tn)*h < ZERO) ) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_BAD_H0); - return(CV_ILL_INPUT); - } - if (h == ZERO) { - tout_hin = tout; - if ( tstopset && (tout-tn)*(tout-tstop) > 0 ) tout_hin = tstop; - hflag = CVHin(cv_mem, tout_hin); - if (hflag != CV_SUCCESS) { - istate = CVHandleFailure(cv_mem, hflag); - return(istate); - } - } - rh = ABS(h)*hmax_inv; - if (rh > ONE) h /= rh; - if (ABS(h) < hmin) h *= hmin/ABS(h); - - /* Check for approach to tstop */ - - if (tstopset) { - if ( (tstop - tn)*h < ZERO ) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_BAD_TSTOP, tstop, tn); - return(CV_ILL_INPUT); - } - if ( (tn + h - tstop)*h > ZERO ) - h = (tstop - tn)*(ONE-FOUR*uround); - } - - /* Scale zn[1] by h.*/ - - hscale = h; - h0u = h; - hprime = h; - - N_VScale(h, zn[1], zn[1]); - - /* Check for zeros of root function g at and near t0. */ - - if (nrtfn > 0) { - - retval = CVRcheck1(cv_mem); - - if (retval == CV_RTFUNC_FAIL) { - CVProcessError(cv_mem, CV_RTFUNC_FAIL, "CVODE", "CVRcheck1", MSGCV_RTFUNC_FAILED, tn); - return(CV_RTFUNC_FAIL); - } - - } - - } /* end of first call block */ - - /* - * ------------------------------------------------------ - * 3. At following steps, perform stop tests: - * - check for root in last step - * - check if we passed tstop - * - check if we passed tout (NORMAL mode) - * - check if current tn was returned (ONE_STEP mode) - * - check if we are close to tstop - * (adjust step size if needed) - * ------------------------------------------------------- - */ - - if (nst > 0) { - - /* Estimate an infinitesimal time interval to be used as - a roundoff for time quantities (based on current time - and step size) */ - troundoff = FUZZ_FACTOR*uround*(ABS(tn) + ABS(h)); - - /* First, check for a root in the last step taken, other than the - last root found, if any. If itask = CV_ONE_STEP and y(tn) was not - returned because of an intervening root, return y(tn) now. */ - if (nrtfn > 0) { - - irfndp = irfnd; - - retval = CVRcheck2(cv_mem); - - if (retval == CLOSERT) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVRcheck2", MSGCV_CLOSE_ROOTS, tlo); - return(CV_ILL_INPUT); - } else if (retval == CV_RTFUNC_FAIL) { - CVProcessError(cv_mem, CV_RTFUNC_FAIL, "CVODE", "CVRcheck2", MSGCV_RTFUNC_FAILED, tlo); - return(CV_RTFUNC_FAIL); - } else if (retval == RTFOUND) { - tretlast = *tret = tlo; - return(CV_ROOT_RETURN); - } - - /* If tn is distinct from tretlast (within roundoff), - check remaining interval for roots */ - if ( ABS(tn - tretlast) > troundoff ) { - - retval = CVRcheck3(cv_mem); - - if (retval == CV_SUCCESS) { /* no root found */ - irfnd = 0; - if ((irfndp == 1) && (itask == CV_ONE_STEP)) { - tretlast = *tret = tn; - N_VScale(ONE, zn[0], yout); - return(CV_SUCCESS); - } - } else if (retval == RTFOUND) { /* a new root was found */ - irfnd = 1; - tretlast = *tret = tlo; - return(CV_ROOT_RETURN); - } else if (retval == CV_RTFUNC_FAIL) { /* g failed */ - CVProcessError(cv_mem, CV_RTFUNC_FAIL, "CVODE", "CVRcheck3", MSGCV_RTFUNC_FAILED, tlo); - return(CV_RTFUNC_FAIL); - } - - } - - } /* end of root stop check */ - - /* In CV_NORMAL mode, test if tout was reached */ - if ( (itask == CV_NORMAL) && ((tn-tout)*h >= ZERO) ) { - tretlast = *tret = tout; - ier = CVodeGetDky(cv_mem, tout, 0, yout); - if (ier != CV_SUCCESS) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_BAD_TOUT, tout); - return(CV_ILL_INPUT); - } - return(CV_SUCCESS); - } - - /* In CV_ONE_STEP mode, test if tn was returned */ - if ( itask == CV_ONE_STEP && ABS(tn - tretlast) > troundoff ) { - tretlast = *tret = tn; - N_VScale(ONE, zn[0], yout); - return(CV_SUCCESS); - } - - /* Test for tn at tstop or near tstop */ - if ( tstopset ) { - - if ( ABS(tn - tstop) <= troundoff) { - ier = CVodeGetDky(cv_mem, tstop, 0, yout); - if (ier != CV_SUCCESS) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_BAD_TSTOP, tstop, tn); - return(CV_ILL_INPUT); - } - tretlast = *tret = tstop; - tstopset = FALSE; - return(CV_TSTOP_RETURN); - } - - /* If next step would overtake tstop, adjust stepsize */ - if ( (tn + hprime - tstop)*h > ZERO ) { - hprime = (tstop - tn)*(ONE-FOUR*uround); - eta = hprime/h; - } - - } - - } /* end stopping tests block */ - - /* - * -------------------------------------------------- - * 4. Looping point for internal steps - * - * 4.1. check for errors (too many steps, too much - * accuracy requested, step size too small) - * 4.2. take a new step (call CVStep) - * 4.3. stop on error - * 4.4. perform stop tests: - * - check for root in last step - * - check if tout was passed - * - check if close to tstop - * - check if in ONE_STEP mode (must return) - * -------------------------------------------------- - */ - - nstloc = 0; - loop { - - next_h = h; - next_q = q; - - /* Reset and check ewt */ - if (nst > 0) { - - ewtsetOK = efun(zn[0], ewt, e_data); - - if (ewtsetOK != 0) { - - if (itol == CV_WF) - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_EWT_NOW_FAIL, tn); - else - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_EWT_NOW_BAD, tn); - - istate = CV_ILL_INPUT; - tretlast = *tret = tn; - N_VScale(ONE, zn[0], yout); - break; - - } - } - - /* Check for too many steps */ - if ( (mxstep>0) && (nstloc >= mxstep) ) { - CVProcessError(cv_mem, CV_TOO_MUCH_WORK, "CVODE", "CVode", MSGCV_MAX_STEPS, tn); - istate = CV_TOO_MUCH_WORK; - tretlast = *tret = tn; - N_VScale(ONE, zn[0], yout); - break; - } - - /* Check for too much accuracy requested */ - nrm = N_VWrmsNorm(zn[0], ewt); - tolsf = uround * nrm; - if (tolsf > ONE) { - CVProcessError(cv_mem, CV_TOO_MUCH_ACC, "CVODE", "CVode", MSGCV_TOO_MUCH_ACC, tn); - istate = CV_TOO_MUCH_ACC; - tretlast = *tret = tn; - N_VScale(ONE, zn[0], yout); - tolsf *= TWO; - break; - } else { - tolsf = ONE; - } - - /* Check for h below roundoff level in tn */ - if (tn + h == tn) { - nhnil++; - if (nhnil <= mxhnil) - CVProcessError(cv_mem, CV_WARNING, "CVODE", "CVode", MSGCV_HNIL, tn, h); - if (nhnil == mxhnil) - CVProcessError(cv_mem, CV_WARNING, "CVODE", "CVode", MSGCV_HNIL_DONE); - } - - /* Call CVStep to take a step */ - kflag = CVStep(cv_mem); - - /* Process failed step cases, and exit loop */ - if (kflag != CV_SUCCESS) { - istate = CVHandleFailure(cv_mem, kflag); - tretlast = *tret = tn; - N_VScale(ONE, zn[0], yout); - break; - } - - nstloc++; - - /* Check for root in last step taken. */ - if (nrtfn > 0) { - - retval = CVRcheck3(cv_mem); - - if (retval == RTFOUND) { /* A new root was found */ - irfnd = 1; - istate = CV_ROOT_RETURN; - tretlast = *tret = tlo; - break; - } else if (retval == CV_RTFUNC_FAIL) { /* g failed */ - CVProcessError(cv_mem, CV_RTFUNC_FAIL, "CVODE", "CVRcheck3", MSGCV_RTFUNC_FAILED, tlo); - istate = CV_RTFUNC_FAIL; - break; - } - - /* If we are at the end of the first step and we still have - * some event functions that are inactive, issue a warning - * as this may indicate a user error in the implementation - * of the root function. */ - - if (nst==1) { - inactive_roots = FALSE; - for (ir=0; ircv_mxgnull > 0) && inactive_roots) { - CVProcessError(cv_mem, CV_WARNING, "CVODES", "CVode", MSGCV_INACTIVE_ROOTS); - } - } - - } - - /* In NORMAL mode, check if tout reached */ - if ( (itask == CV_NORMAL) && (tn-tout)*h >= ZERO ) { - istate = CV_SUCCESS; - tretlast = *tret = tout; - (void) CVodeGetDky(cv_mem, tout, 0, yout); - next_q = qprime; - next_h = hprime; - break; - } - - /* Check if tn is at tstop or near tstop */ - if ( tstopset ) { - - troundoff = FUZZ_FACTOR*uround*(ABS(tn) + ABS(h)); - if ( ABS(tn - tstop) <= troundoff) { - (void) CVodeGetDky(cv_mem, tstop, 0, yout); - tretlast = *tret = tstop; - tstopset = FALSE; - istate = CV_TSTOP_RETURN; - break; - } - - if ( (tn + hprime - tstop)*h > ZERO ) { - hprime = (tstop - tn)*(ONE-FOUR*uround); - eta = hprime/h; - } - - } - - /* In ONE_STEP mode, copy y and exit loop */ - if (itask == CV_ONE_STEP) { - istate = CV_SUCCESS; - tretlast = *tret = tn; - N_VScale(ONE, zn[0], yout); - next_q = qprime; - next_h = hprime; - break; - } - - } /* end looping for internal steps */ - - return(istate); -} - -/*-----------------------------------------------------------------*/ - -/* - * CVodeGetDky - * - * This routine computes the k-th derivative of the interpolating - * polynomial at the time t and stores the result in the vector dky. - * The formula is: - * q - * dky = SUM c(j,k) * (t - tn)^(j-k) * h^(-j) * zn[j] , - * j=k - * where c(j,k) = j*(j-1)*...*(j-k+1), q is the current order, and - * zn[j] is the j-th column of the Nordsieck history array. - * - * This function is called by CVode with k = 0 and t = tout, but - * may also be called directly by the user. - */ - -int CVodeGetDky(void *cvode_mem, realtype t, int k, N_Vector dky) -{ - realtype s, c, r; - realtype tfuzz, tp, tn1; - int i, j; - CVodeMem cv_mem; - - /* Check all inputs for legality */ - - if (cvode_mem == NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetDky", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - if (dky == NULL) { - CVProcessError(cv_mem, CV_BAD_DKY, "CVODE", "CVodeGetDky", MSGCV_NULL_DKY); - return(CV_BAD_DKY); - } - - if ((k < 0) || (k > q)) { - CVProcessError(cv_mem, CV_BAD_K, "CVODE", "CVodeGetDky", MSGCV_BAD_K); - return(CV_BAD_K); - } - - /* Allow for some slack */ - tfuzz = FUZZ_FACTOR * uround * (ABS(tn) + ABS(hu)); - if (hu < ZERO) tfuzz = -tfuzz; - tp = tn - hu - tfuzz; - tn1 = tn + tfuzz; - if ((t-tp)*(t-tn1) > ZERO) { - CVProcessError(cv_mem, CV_BAD_T, "CVODE", "CVodeGetDky", MSGCV_BAD_T, t, tn-hu, tn); - return(CV_BAD_T); - } - - /* Sum the differentiated interpolating polynomial */ - - s = (t - tn) / h; - for (j=q; j >= k; j--) { - c = ONE; - for (i=j; i >= j-k+1; i--) c *= i; - if (j == q) { - N_VScale(c, zn[q], dky); - } else { - N_VLinearSum(c, zn[j], s, dky, dky); - } - } - if (k == 0) return(CV_SUCCESS); - r = RPowerI(h,-k); - N_VScale(r, dky, dky); - return(CV_SUCCESS); -} - -/* - * CVodeFree - * - * This routine frees the problem memory allocated by CVodeInit. - * Such memory includes all the vectors allocated by CVAllocVectors, - * and the memory lmem for the linear solver (deallocated by a call - * to lfree). - */ - -void CVodeFree(void **cvode_mem) -{ - CVodeMem cv_mem; - - if (*cvode_mem == NULL) return; - - cv_mem = (CVodeMem) (*cvode_mem); - - CVFreeVectors(cv_mem); - - if (iter == CV_NEWTON && lfree != NULL) lfree(cv_mem); - - if (nrtfn > 0) { - free(glo); glo = NULL; - free(ghi); ghi = NULL; - free(grout); grout = NULL; - free(iroots); iroots = NULL; - free(rootdir); rootdir = NULL; - free(gactive); gactive = NULL; - } - - free(*cvode_mem); - *cvode_mem = NULL; -} - -/* - * ================================================================= - * Private Functions Implementation - * ================================================================= - */ - -/* - * CVCheckNvector - * This routine checks if all required vector operations are present. - * If any of them is missing it returns FALSE. - */ - -static booleantype CVCheckNvector(N_Vector tmpl) -{ - if((tmpl->ops->nvclone == NULL) || - (tmpl->ops->nvdestroy == NULL) || - (tmpl->ops->nvlinearsum == NULL) || - (tmpl->ops->nvconst == NULL) || - (tmpl->ops->nvprod == NULL) || - (tmpl->ops->nvdiv == NULL) || - (tmpl->ops->nvscale == NULL) || - (tmpl->ops->nvabs == NULL) || - (tmpl->ops->nvinv == NULL) || - (tmpl->ops->nvaddconst == NULL) || - (tmpl->ops->nvmaxnorm == NULL) || - (tmpl->ops->nvwrmsnorm == NULL) || - (tmpl->ops->nvmin == NULL)) - return(FALSE); - else - return(TRUE); -} - -/* - * CVAllocVectors - * - * This routine allocates the CVODE vectors ewt, acor, tempv, ftemp, and - * zn[0], ..., zn[maxord]. - * If all memory allocations are successful, CVAllocVectors returns TRUE. - * Otherwise all allocated memory is freed and CVAllocVectors returns FALSE. - * This routine also sets the optional outputs lrw and liw, which are - * (respectively) the lengths of the real and integer work spaces - * allocated here. - */ - -static booleantype CVAllocVectors(CVodeMem cv_mem, N_Vector tmpl) -{ - int i, j; - - /* Allocate ewt, acor, tempv, ftemp */ - - ewt = N_VClone(tmpl); - if (ewt == NULL) return(FALSE); - - acor = N_VClone(tmpl); - if (acor == NULL) { - N_VDestroy(ewt); - return(FALSE); - } - - tempv = N_VClone(tmpl); - if (tempv == NULL) { - N_VDestroy(ewt); - N_VDestroy(acor); - return(FALSE); - } - - ftemp = N_VClone(tmpl); - if (ftemp == NULL) { - N_VDestroy(tempv); - N_VDestroy(ewt); - N_VDestroy(acor); - return(FALSE); - } - - /* Allocate zn[0] ... zn[qmax] */ - - for (j=0; j <= qmax; j++) { - zn[j] = N_VClone(tmpl); - if (zn[j] == NULL) { - N_VDestroy(ewt); - N_VDestroy(acor); - N_VDestroy(tempv); - N_VDestroy(ftemp); - for (i=0; i < j; i++) N_VDestroy(zn[i]); - return(FALSE); - } - } - - /* Update solver workspace lengths */ - lrw += (qmax + 5)*lrw1; - liw += (qmax + 5)*liw1; - - /* Store the value of qmax used here */ - cv_mem->cv_qmax_alloc = qmax; - - return(TRUE); -} - -/* - * CVFreeVectors - * - * This routine frees the CVODE vectors allocated in CVAllocVectors. - */ - -static void CVFreeVectors(CVodeMem cv_mem) -{ - int j, maxord; - - maxord = cv_mem->cv_qmax_alloc; - - N_VDestroy(ewt); - N_VDestroy(acor); - N_VDestroy(tempv); - N_VDestroy(ftemp); - for(j=0; j <= maxord; j++) N_VDestroy(zn[j]); - - lrw -= (maxord + 5)*lrw1; - liw -= (maxord + 5)*liw1; - - if (cv_mem->cv_VabstolMallocDone) { - N_VDestroy(Vabstol); - lrw -= lrw1; - liw -= liw1; - } -} - -/* - * CVInitialSetup - * - * This routine performs input consistency checks at the first step. - * If needed, it also checks the linear solver module and calls the - * linear solver initialization routine. - */ - -static int CVInitialSetup(CVodeMem cv_mem) -{ - int ier; - - /* Did the user specify tolerances? */ - if (itol == CV_NN) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVInitialSetup", MSGCV_NO_TOLS); - return(CV_ILL_INPUT); - } - - /* Set data for efun */ - if (cv_mem->cv_user_efun) e_data = user_data; - else e_data = cv_mem; - - /* Load initial error weights */ - ier = efun(zn[0], ewt, e_data); - if (ier != 0) { - if (itol == CV_WF) - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVInitialSetup", MSGCV_EWT_FAIL); - else - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVInitialSetup", MSGCV_BAD_EWT); - return(CV_ILL_INPUT); - } - - /* Check if lsolve function exists (if needed) and call linit function (if it exists) */ - if (iter == CV_NEWTON) { - if (lsolve == NULL) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVInitialSetup", MSGCV_LSOLVE_NULL); - return(CV_ILL_INPUT); - } - if (linit != NULL) { - ier = linit(cv_mem); - if (ier != 0) { - CVProcessError(cv_mem, CV_LINIT_FAIL, "CVODE", "CVInitialSetup", MSGCV_LINIT_FAIL); - return(CV_LINIT_FAIL); - } - } - } - - return(CV_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * PRIVATE FUNCTIONS FOR CVODE - * ----------------------------------------------------------------- - */ - -/* - * CVHin - * - * This routine computes a tentative initial step size h0. - * If tout is too close to tn (= t0), then CVHin returns CV_TOO_CLOSE - * and h remains uninitialized. Note that here tout is either the value - * passed to CVode at the first call or the value of tstop (if tstop is - * enabled and it is closer to t0=tn than tout). - * If the RHS function fails unrecoverably, CVHin returns CV_RHSFUNC_FAIL. - * If the RHS function fails recoverably too many times and recovery is - * not possible, CVHin returns CV_REPTD_RHSFUNC_ERR. - * Otherwise, CVHin sets h to the chosen value h0 and returns CV_SUCCESS. - * - * The algorithm used seeks to find h0 as a solution of - * (WRMS norm of (h0^2 ydd / 2)) = 1, - * where ydd = estimated second derivative of y. - * - * We start with an initial estimate equal to the geometric mean of the - * lower and upper bounds on the step size. - * - * Loop up to MAX_ITERS times to find h0. - * Stop if new and previous values differ by a factor < 2. - * Stop if hnew/hg > 2 after one iteration, as this probably means - * that the ydd value is bad because of cancellation error. - * - * For each new proposed hg, we allow MAX_ITERS attempts to - * resolve a possible recoverable failure from f() by reducing - * the proposed stepsize by a factor of 0.2. If a legal stepsize - * still cannot be found, fall back on a previous value if possible, - * or else return CV_REPTD_RHSFUNC_ERR. - * - * Finally, we apply a bias (0.5) and verify that h0 is within bounds. - */ - -static int CVHin(CVodeMem cv_mem, realtype tout) -{ - int retval, sign, count1, count2; - realtype tdiff, tdist, tround, hlb, hub; - realtype hg, hgs, hs, hnew, hrat, h0, yddnrm; - booleantype hgOK, hnewOK; - - /* If tout is too close to tn, give up */ - - if ((tdiff = tout-tn) == ZERO) return(CV_TOO_CLOSE); - - sign = (tdiff > ZERO) ? 1 : -1; - tdist = ABS(tdiff); - tround = uround * MAX(ABS(tn), ABS(tout)); - - if (tdist < TWO*tround) return(CV_TOO_CLOSE); - - /* - Set lower and upper bounds on h0, and take geometric mean - as first trial value. - Exit with this value if the bounds cross each other. - */ - - hlb = HLB_FACTOR * tround; - hub = CVUpperBoundH0(cv_mem, tdist); - - hg = RSqrt(hlb*hub); - - if (hub < hlb) { - if (sign == -1) h = -hg; - else h = hg; - return(CV_SUCCESS); - } - - /* Outer loop */ - - hnewOK = FALSE; - hs = hg; /* safeguard against 'uninitialized variable' warning */ - - for(count1 = 1; count1 <= MAX_ITERS; count1++) { - - /* Attempts to estimate ydd */ - - hgOK = FALSE; - - for (count2 = 1; count2 <= MAX_ITERS; count2++) { - hgs = hg*sign; - retval = CVYddNorm(cv_mem, hgs, &yddnrm); - /* If f() failed unrecoverably, give up */ - if (retval < 0) return(CV_RHSFUNC_FAIL); - /* If successful, we can use ydd */ - if (retval == CV_SUCCESS) {hgOK = TRUE; break;} - /* f() failed recoverably; cut step size and test it again */ - hg *= POINT2; - } - - /* If f() failed recoverably MAX_ITERS times */ - - if (!hgOK) { - /* Exit if this is the first or second pass. No recovery possible */ - if (count1 <= 2) return(CV_REPTD_RHSFUNC_ERR); - /* We have a fall-back option. The value hs is a previous hnew which - passed through f(). Use it and break */ - hnew = hs; - break; - } - - /* The proposed step size is feasible. Save it. */ - hs = hg; - - /* If the stopping criteria was met, or if this is the last pass, stop */ - if ( (hnewOK) || (count1 == MAX_ITERS)) {hnew = hg; break;} - - /* Propose new step size */ - hnew = (yddnrm*hub*hub > TWO) ? RSqrt(TWO/yddnrm) : RSqrt(hg*hub); - hrat = hnew/hg; - - /* Accept hnew if it does not differ from hg by more than a factor of 2 */ - if ((hrat > HALF) && (hrat < TWO)) { - hnewOK = TRUE; - } - - /* After one pass, if ydd seems to be bad, use fall-back value. */ - if ((count1 > 1) && (hrat > TWO)) { - hnew = hg; - hnewOK = TRUE; - } - - /* Send this value back through f() */ - hg = hnew; - - } - - /* Apply bounds, bias factor, and attach sign */ - - h0 = H_BIAS*hnew; - if (h0 < hlb) h0 = hlb; - if (h0 > hub) h0 = hub; - if (sign == -1) h0 = -h0; - h = h0; - - return(CV_SUCCESS); -} - -/* - * CVUpperBoundH0 - * - * This routine sets an upper bound on abs(h0) based on - * tdist = tn - t0 and the values of y[i]/y'[i]. - */ - -static realtype CVUpperBoundH0(CVodeMem cv_mem, realtype tdist) -{ - realtype hub_inv, hub; - N_Vector temp1, temp2; - - /* - * Bound based on |y0|/|y0'| -- allow at most an increase of - * HUB_FACTOR in y0 (based on a forward Euler step). The weight - * factor is used as a safeguard against zero components in y0. - */ - - temp1 = tempv; - temp2 = acor; - - N_VAbs(zn[0], temp2); - efun(zn[0], temp1, e_data); - N_VInv(temp1, temp1); - N_VLinearSum(HUB_FACTOR, temp2, ONE, temp1, temp1); - - N_VAbs(zn[1], temp2); - - N_VDiv(temp2, temp1, temp1); - hub_inv = N_VMaxNorm(temp1); - - /* - * bound based on tdist -- allow at most a step of magnitude - * HUB_FACTOR * tdist - */ - - hub = HUB_FACTOR*tdist; - - /* Use the smaler of the two */ - - if (hub*hub_inv > ONE) hub = ONE/hub_inv; - - return(hub); -} - -/* - * CVYddNorm - * - * This routine computes an estimate of the second derivative of y - * using a difference quotient, and returns its WRMS norm. - */ - -static int CVYddNorm(CVodeMem cv_mem, realtype hg, realtype *yddnrm) -{ - int retval; - - N_VLinearSum(hg, zn[1], ONE, zn[0], y); - retval = f(tn+hg, y, tempv, user_data); - nfe++; - if (retval < 0) return(CV_RHSFUNC_FAIL); - if (retval > 0) return(RHSFUNC_RECVR); - - N_VLinearSum(ONE, tempv, -ONE, zn[1], tempv); - N_VScale(ONE/hg, tempv, tempv); - - *yddnrm = N_VWrmsNorm(tempv, ewt); - - return(CV_SUCCESS); -} - -/* - * CVStep - * - * This routine performs one internal cvode step, from tn to tn + h. - * It calls other routines to do all the work. - * - * The main operations done here are as follows: - * - preliminary adjustments if a new step size was chosen; - * - prediction of the Nordsieck history array zn at tn + h; - * - setting of multistep method coefficients and test quantities; - * - solution of the nonlinear system; - * - testing the local error; - * - updating zn and other state data if successful; - * - resetting stepsize and order for the next step. - * - if SLDET is on, check for stability, reduce order if necessary. - * On a failure in the nonlinear system solution or error test, the - * step may be reattempted, depending on the nature of the failure. - */ - -static int CVStep(CVodeMem cv_mem) -{ - realtype saved_t, dsm; - int ncf, nef; - int nflag, kflag, eflag; - - saved_t = tn; - ncf = nef = 0; - nflag = FIRST_CALL; - - if ((nst > 0) && (hprime != h)) CVAdjustParams(cv_mem); - - /* Looping point for attempts to take a step */ - loop { - - CVPredict(cv_mem); - CVSet(cv_mem); - - nflag = CVNls(cv_mem, nflag); - kflag = CVHandleNFlag(cv_mem, &nflag, saved_t, &ncf); - - /* Go back in loop if we need to predict again (nflag=PREV_CONV_FAIL)*/ - if (kflag == PREDICT_AGAIN) continue; - - /* Return if nonlinear solve failed and recovery not possible. */ - if (kflag != DO_ERROR_TEST) return(kflag); - - /* Perform error test (nflag=CV_SUCCESS) */ - eflag = CVDoErrorTest(cv_mem, &nflag, saved_t, &nef, &dsm); - - /* Go back in loop if we need to predict again (nflag=PREV_ERR_FAIL) */ - if (eflag == TRY_AGAIN) continue; - - /* Return if error test failed and recovery not possible. */ - if (eflag != CV_SUCCESS) return(eflag); - - /* Error test passed (eflag=CV_SUCCESS), break from loop */ - break; - - } - - /* Nonlinear system solve and error test were both successful. - Update data, and consider change of step and/or order. */ - - CVCompleteStep(cv_mem); - - CVPrepareNextStep(cv_mem, dsm); - - /* If Stablilty Limit Detection is turned on, call stability limit - detection routine for possible order reduction. */ - - if (sldeton) CVBDFStab(cv_mem); - - etamax = (nst <= SMALL_NST) ? ETAMX2 : ETAMX3; - - /* Finally, we rescale the acor array to be the - estimated local error vector. */ - - N_VScale(tq[2], acor, acor); - return(CV_SUCCESS); - -} - -/* - * CVAdjustParams - * - * This routine is called when a change in step size was decided upon, - * and it handles the required adjustments to the history array zn. - * If there is to be a change in order, we call CVAdjustOrder and reset - * q, L = q+1, and qwait. Then in any case, we call CVRescale, which - * resets h and rescales the Nordsieck array. - */ - -static void CVAdjustParams(CVodeMem cv_mem) -{ - if (qprime != q) { - CVAdjustOrder(cv_mem, qprime-q); - q = qprime; - L = q+1; - qwait = L; - } - CVRescale(cv_mem); -} - -/* - * CVAdjustOrder - * - * This routine is a high level routine which handles an order - * change by an amount deltaq (= +1 or -1). If a decrease in order - * is requested and q==2, then the routine returns immediately. - * Otherwise CVAdjustAdams or CVAdjustBDF is called to handle the - * order change (depending on the value of lmm). - */ - -static void CVAdjustOrder(CVodeMem cv_mem, int deltaq) -{ - if ((q==2) && (deltaq != 1)) return; - - switch(lmm){ - case CV_ADAMS: - CVAdjustAdams(cv_mem, deltaq); - break; - case CV_BDF: - CVAdjustBDF(cv_mem, deltaq); - break; - } -} - -/* - * CVAdjustAdams - * - * This routine adjusts the history array on a change of order q by - * deltaq, in the case that lmm == CV_ADAMS. - */ - -static void CVAdjustAdams(CVodeMem cv_mem, int deltaq) -{ - int i, j; - realtype xi, hsum; - - /* On an order increase, set new column of zn to zero and return */ - - if (deltaq==1) { - N_VConst(ZERO, zn[L]); - return; - } - - /* - * On an order decrease, each zn[j] is adjusted by a multiple of zn[q]. - * The coeffs. in the adjustment are the coeffs. of the polynomial: - * x - * q * INT { u * ( u + xi_1 ) * ... * ( u + xi_{q-2} ) } du - * 0 - * where xi_j = [t_n - t_(n-j)]/h => xi_0 = 0 - */ - - for (i=0; i <= qmax; i++) l[i] = ZERO; - l[1] = ONE; - hsum = ZERO; - for (j=1; j <= q-2; j++) { - hsum += tau[j]; - xi = hsum / hscale; - for (i=j+1; i >= 1; i--) l[i] = l[i]*xi + l[i-1]; - } - - for (j=1; j <= q-2; j++) l[j+1] = q * (l[j] / (j+1)); - - for (j=2; j < q; j++) - N_VLinearSum(-l[j], zn[q], ONE, zn[j], zn[j]); -} - -/* - * CVAdjustBDF - * - * This is a high level routine which handles adjustments to the - * history array on a change of order by deltaq in the case that - * lmm == CV_BDF. CVAdjustBDF calls CVIncreaseBDF if deltaq = +1 and - * CVDecreaseBDF if deltaq = -1 to do the actual work. - */ - -static void CVAdjustBDF(CVodeMem cv_mem, int deltaq) -{ - switch(deltaq) { - case 1 : - CVIncreaseBDF(cv_mem); - return; - case -1: - CVDecreaseBDF(cv_mem); - return; - } -} - -/* - * CVIncreaseBDF - * - * This routine adjusts the history array on an increase in the - * order q in the case that lmm == CV_BDF. - * A new column zn[q+1] is set equal to a multiple of the saved - * vector (= acor) in zn[indx_acor]. Then each zn[j] is adjusted by - * a multiple of zn[q+1]. The coefficients in the adjustment are the - * coefficients of the polynomial x*x*(x+xi_1)*...*(x+xi_j), - * where xi_j = [t_n - t_(n-j)]/h. - */ - -static void CVIncreaseBDF(CVodeMem cv_mem) -{ - realtype alpha0, alpha1, prod, xi, xiold, hsum, A1; - int i, j; - - for (i=0; i <= qmax; i++) l[i] = ZERO; - l[2] = alpha1 = prod = xiold = ONE; - alpha0 = -ONE; - hsum = hscale; - if (q > 1) { - for (j=1; j < q; j++) { - hsum += tau[j+1]; - xi = hsum / hscale; - prod *= xi; - alpha0 -= ONE / (j+1); - alpha1 += ONE / xi; - for (i=j+2; i >= 2; i--) l[i] = l[i]*xiold + l[i-1]; - xiold = xi; - } - } - A1 = (-alpha0 - alpha1) / prod; - N_VScale(A1, zn[indx_acor], zn[L]); - for (j=2; j <= q; j++) { - N_VLinearSum(l[j], zn[L], ONE, zn[j], zn[j]); - } -} - -/* - * CVDecreaseBDF - * - * This routine adjusts the history array on a decrease in the - * order q in the case that lmm == CV_BDF. - * Each zn[j] is adjusted by a multiple of zn[q]. The coefficients - * in the adjustment are the coefficients of the polynomial - * x*x*(x+xi_1)*...*(x+xi_j), where xi_j = [t_n - t_(n-j)]/h. - */ - -static void CVDecreaseBDF(CVodeMem cv_mem) -{ - realtype hsum, xi; - int i, j; - - for (i=0; i <= qmax; i++) l[i] = ZERO; - l[2] = ONE; - hsum = ZERO; - for(j=1; j <= q-2; j++) { - hsum += tau[j]; - xi = hsum /hscale; - for (i=j+2; i >= 2; i--) l[i] = l[i]*xi + l[i-1]; - } - - for(j=2; j < q; j++) - N_VLinearSum(-l[j], zn[q], ONE, zn[j], zn[j]); -} - -/* - * CVRescale - * - * This routine rescales the Nordsieck array by multiplying the - * jth column zn[j] by eta^j, j = 1, ..., q. Then the value of - * h is rescaled by eta, and hscale is reset to h. - */ - -static void CVRescale(CVodeMem cv_mem) -{ - int j; - realtype factor; - - factor = eta; - for (j=1; j <= q; j++) { - N_VScale(factor, zn[j], zn[j]); - factor *= eta; - } - h = hscale * eta; - next_h = h; - hscale = h; - nscon = 0; -} - -/* - * CVPredict - * - * This routine advances tn by the tentative step size h, and computes - * the predicted array z_n(0), which is overwritten on zn. The - * prediction of zn is done by repeated additions. - * If tstop is enabled, it is possible for tn + h to be past tstop by roundoff, - * and in that case, we reset tn (after incrementing by h) to tstop. - */ - -static void CVPredict(CVodeMem cv_mem) -{ - int j, k; - - tn += h; - if (tstopset) { - if ((tn - tstop)*h > ZERO) tn = tstop; - } - for (k = 1; k <= q; k++) - for (j = q; j >= k; j--) - N_VLinearSum(ONE, zn[j-1], ONE, zn[j], zn[j-1]); -} - -/* - * CVSet - * - * This routine is a high level routine which calls CVSetAdams or - * CVSetBDF to set the polynomial l, the test quantity array tq, - * and the related variables rl1, gamma, and gamrat. - * - * The array tq is loaded with constants used in the control of estimated - * local errors and in the nonlinear convergence test. Specifically, while - * running at order q, the components of tq are as follows: - * tq[1] = a coefficient used to get the est. local error at order q-1 - * tq[2] = a coefficient used to get the est. local error at order q - * tq[3] = a coefficient used to get the est. local error at order q+1 - * tq[4] = constant used in nonlinear iteration convergence test - * tq[5] = coefficient used to get the order q+2 derivative vector used in - * the est. local error at order q+1 - */ - -static void CVSet(CVodeMem cv_mem) -{ - switch(lmm) { - case CV_ADAMS: - CVSetAdams(cv_mem); - break; - case CV_BDF: - CVSetBDF(cv_mem); - break; - } - rl1 = ONE / l[1]; - gamma = h * rl1; - if (nst == 0) gammap = gamma; - gamrat = (nst > 0) ? gamma / gammap : ONE; /* protect x / x != 1.0 */ -} - -/* - * CVSetAdams - * - * This routine handles the computation of l and tq for the - * case lmm == CV_ADAMS. - * - * The components of the array l are the coefficients of a - * polynomial Lambda(x) = l_0 + l_1 x + ... + l_q x^q, given by - * q-1 - * (d/dx) Lambda(x) = c * PRODUCT (1 + x / xi_i) , where - * i=1 - * Lambda(-1) = 0, Lambda(0) = 1, and c is a normalization factor. - * Here xi_i = [t_n - t_(n-i)] / h. - * - * The array tq is set to test quantities used in the convergence - * test, the error test, and the selection of h at a new order. - */ - -static void CVSetAdams(CVodeMem cv_mem) -{ - realtype m[L_MAX], M[3], hsum; - - if (q == 1) { - l[0] = l[1] = tq[1] = tq[5] = ONE; - tq[2] = HALF; - tq[3] = ONE/TWELVE; - tq[4] = nlscoef / tq[2]; /* = 0.1 / tq[2] */ - return; - } - - hsum = CVAdamsStart(cv_mem, m); - - M[0] = CVAltSum(q-1, m, 1); - M[1] = CVAltSum(q-1, m, 2); - - CVAdamsFinish(cv_mem, m, M, hsum); -} - -/* - * CVAdamsStart - * - * This routine generates in m[] the coefficients of the product - * polynomial needed for the Adams l and tq coefficients for q > 1. - */ - -static realtype CVAdamsStart(CVodeMem cv_mem, realtype m[]) -{ - realtype hsum, xi_inv, sum; - int i, j; - - hsum = h; - m[0] = ONE; - for (i=1; i <= q; i++) m[i] = ZERO; - for (j=1; j < q; j++) { - if ((j==q-1) && (qwait == 1)) { - sum = CVAltSum(q-2, m, 2); - tq[1] = q * sum / m[q-2]; - } - xi_inv = h / hsum; - for (i=j; i >= 1; i--) m[i] += m[i-1] * xi_inv; - hsum += tau[j]; - /* The m[i] are coefficients of product(1 to j) (1 + x/xi_i) */ - } - return(hsum); -} - -/* - * CVAdamsFinish - * - * This routine completes the calculation of the Adams l and tq. - */ - -static void CVAdamsFinish(CVodeMem cv_mem, realtype m[], realtype M[], realtype hsum) -{ - int i; - realtype M0_inv, xi, xi_inv; - - M0_inv = ONE / M[0]; - - l[0] = ONE; - for (i=1; i <= q; i++) l[i] = M0_inv * (m[i-1] / i); - xi = hsum / h; - xi_inv = ONE / xi; - - tq[2] = M[1] * M0_inv / xi; - tq[5] = xi / l[q]; - - if (qwait == 1) { - for (i=q; i >= 1; i--) m[i] += m[i-1] * xi_inv; - M[2] = CVAltSum(q, m, 2); - tq[3] = M[2] * M0_inv / L; - } - - tq[4] = nlscoef / tq[2]; -} - -/* - * CVAltSum - * - * CVAltSum returns the value of the alternating sum - * sum (i= 0 ... iend) [ (-1)^i * (a[i] / (i + k)) ]. - * If iend < 0 then CVAltSum returns 0. - * This operation is needed to compute the integral, from -1 to 0, - * of a polynomial x^(k-1) M(x) given the coefficients of M(x). - */ - -static realtype CVAltSum(int iend, realtype a[], int k) -{ - int i, sign; - realtype sum; - - if (iend < 0) return(ZERO); - - sum = ZERO; - sign = 1; - for (i=0; i <= iend; i++) { - sum += sign * (a[i] / (i+k)); - sign = -sign; - } - return(sum); -} - -/* - * CVSetBDF - * - * This routine computes the coefficients l and tq in the case - * lmm == CV_BDF. CVSetBDF calls CVSetTqBDF to set the test - * quantity array tq. - * - * The components of the array l are the coefficients of a - * polynomial Lambda(x) = l_0 + l_1 x + ... + l_q x^q, given by - * q-1 - * Lambda(x) = (1 + x / xi*_q) * PRODUCT (1 + x / xi_i) , where - * i=1 - * xi_i = [t_n - t_(n-i)] / h. - * - * The array tq is set to test quantities used in the convergence - * test, the error test, and the selection of h at a new order. - */ - -static void CVSetBDF(CVodeMem cv_mem) -{ - realtype alpha0, alpha0_hat, xi_inv, xistar_inv, hsum; - int i,j; - - l[0] = l[1] = xi_inv = xistar_inv = ONE; - for (i=2; i <= q; i++) l[i] = ZERO; - alpha0 = alpha0_hat = -ONE; - hsum = h; - if (q > 1) { - for (j=2; j < q; j++) { - hsum += tau[j-1]; - xi_inv = h / hsum; - alpha0 -= ONE / j; - for(i=j; i >= 1; i--) l[i] += l[i-1]*xi_inv; - /* The l[i] are coefficients of product(1 to j) (1 + x/xi_i) */ - } - - /* j = q */ - alpha0 -= ONE / q; - xistar_inv = -l[1] - alpha0; - hsum += tau[q-1]; - xi_inv = h / hsum; - alpha0_hat = -l[1] - xi_inv; - for (i=q; i >= 1; i--) l[i] += l[i-1]*xistar_inv; - } - - CVSetTqBDF(cv_mem, hsum, alpha0, alpha0_hat, xi_inv, xistar_inv); -} - -/* - * CVSetTqBDF - * - * This routine sets the test quantity array tq in the case - * lmm == CV_BDF. - */ - -static void CVSetTqBDF(CVodeMem cv_mem, realtype hsum, realtype alpha0, - realtype alpha0_hat, realtype xi_inv, realtype xistar_inv) -{ - realtype A1, A2, A3, A4, A5, A6; - realtype C, Cpinv, Cppinv; - - A1 = ONE - alpha0_hat + alpha0; - A2 = ONE + q * A1; - tq[2] = ABS(A1 / (alpha0 * A2)); - tq[5] = ABS(A2 * xistar_inv / (l[q] * xi_inv)); - if (qwait == 1) { - C = xistar_inv / l[q]; - A3 = alpha0 + ONE / q; - A4 = alpha0_hat + xi_inv; - Cpinv = (ONE - A4 + A3) / A3; - tq[1] = ABS(C * Cpinv); - hsum += tau[q]; - xi_inv = h / hsum; - A5 = alpha0 - (ONE / (q+1)); - A6 = alpha0_hat - xi_inv; - Cppinv = (ONE - A6 + A5) / A2; - tq[3] = ABS(Cppinv / (xi_inv * (q+2) * A5)); - } - tq[4] = nlscoef / tq[2]; -} - -/* - * CVNls - * - * This routine attempts to solve the nonlinear system associated - * with a single implicit step of the linear multistep method. - * Depending on iter, it calls CVNlsFunctional or CVNlsNewton - * to do the work. - */ - -static int CVNls(CVodeMem cv_mem, int nflag) -{ - int flag = CV_SUCCESS; - - switch(iter) { - case CV_FUNCTIONAL: - flag = CVNlsFunctional(cv_mem); - break; - case CV_NEWTON: - flag = CVNlsNewton(cv_mem, nflag); - break; - } - - return(flag); -} - -/* - * CVNlsFunctional - * - * This routine attempts to solve the nonlinear system using - * functional iteration (no matrices involved). - * - * Possible return values are: - * - * CV_SUCCESS ---> continue with error test - * - * CV_RHSFUNC_FAIL ---> halt the integration - * - * CONV_FAIL -+ - * RHSFUNC_RECVR -+-> predict again or stop if too many - * - */ - -static int CVNlsFunctional(CVodeMem cv_mem) -{ - int retval, m; - realtype del, delp, dcon; - - /* Initialize counter and evaluate f at predicted y */ - - crate = ONE; - m = 0; - - retval = f(tn, zn[0], tempv, user_data); - nfe++; - if (retval < 0) return(CV_RHSFUNC_FAIL); - if (retval > 0) return(RHSFUNC_RECVR); - - N_VConst(ZERO, acor); - - /* Initialize delp to avoid compiler warning message */ - del = delp = ZERO; - - /* Loop until convergence; accumulate corrections in acor */ - - loop { - - nni++; - - /* Correct y directly from the last f value */ - N_VLinearSum(h, tempv, -ONE, zn[1], tempv); - N_VScale(rl1, tempv, tempv); - N_VLinearSum(ONE, zn[0], ONE, tempv, y); - /* Get WRMS norm of current correction to use in convergence test */ - N_VLinearSum(ONE, tempv, -ONE, acor, acor); - del = N_VWrmsNorm(acor, ewt); - N_VScale(ONE, tempv, acor); - - /* Test for convergence. If m > 0, an estimate of the convergence - rate constant is stored in crate, and used in the test. */ - if (m > 0) crate = MAX(CRDOWN * crate, del / delp); - dcon = del * MIN(ONE, crate) / tq[4]; - if (dcon <= ONE) { - acnrm = (m == 0) ? del : N_VWrmsNorm(acor, ewt); - return(CV_SUCCESS); /* Convergence achieved */ - } - - /* Stop at maxcor iterations or if iter. seems to be diverging */ - m++; - if ((m==maxcor) || ((m >= 2) && (del > RDIV * delp))) return(CONV_FAIL); - - /* Save norm of correction, evaluate f, and loop again */ - delp = del; - - retval = f(tn, y, tempv, user_data); - nfe++; - if (retval < 0) return(CV_RHSFUNC_FAIL); - if (retval > 0) return(RHSFUNC_RECVR); - - } -} - -/* - * CVNlsNewton - * - * This routine handles the Newton iteration. It calls lsetup if - * indicated, calls CVNewtonIteration to perform the iteration, and - * retries a failed attempt at Newton iteration if that is indicated. - * - * Possible return values: - * - * CV_SUCCESS ---> continue with error test - * - * CV_RHSFUNC_FAIL -+ - * CV_LSETUP_FAIL |-> halt the integration - * CV_LSOLVE_FAIL -+ - * - * CONV_FAIL -+ - * RHSFUNC_RECVR -+-> predict again or stop if too many - * - */ - -static int CVNlsNewton(CVodeMem cv_mem, int nflag) -{ - N_Vector vtemp1, vtemp2, vtemp3; - int convfail, retval, ier; - booleantype callSetup; - - vtemp1 = acor; /* rename acor as vtemp1 for readability */ - vtemp2 = y; /* rename y as vtemp2 for readability */ - vtemp3 = tempv; /* rename tempv as vtemp3 for readability */ - - /* Set flag convfail, input to lsetup for its evaluation decision */ - convfail = ((nflag == FIRST_CALL) || (nflag == PREV_ERR_FAIL)) ? - CV_NO_FAILURES : CV_FAIL_OTHER; - - /* Decide whether or not to call setup routine (if one exists) */ - if (setupNonNull) { - callSetup = (nflag == PREV_CONV_FAIL) || (nflag == PREV_ERR_FAIL) || - (nst == 0) || (nst >= nstlp + MSBP) || (ABS(gamrat-ONE) > DGMAX); - } else { - crate = ONE; - callSetup = FALSE; - } - - /* Looping point for the solution of the nonlinear system. - Evaluate f at the predicted y, call lsetup if indicated, and - call CVNewtonIteration for the Newton iteration itself. */ - - loop { - - retval = f(tn, zn[0], ftemp, user_data); - nfe++; - if (retval < 0) return(CV_RHSFUNC_FAIL); - if (retval > 0) return(RHSFUNC_RECVR); - - if (callSetup) { - ier = lsetup(cv_mem, convfail, zn[0], ftemp, &jcur, - vtemp1, vtemp2, vtemp3); - nsetups++; - callSetup = FALSE; - gamrat = crate = ONE; - gammap = gamma; - nstlp = nst; - /* Return if lsetup failed */ - if (ier < 0) return(CV_LSETUP_FAIL); - if (ier > 0) return(CONV_FAIL); - } - - /* Set acor to zero and load prediction into y vector */ - N_VConst(ZERO, acor); - N_VScale(ONE, zn[0], y); - - /* Do the Newton iteration */ - ier = CVNewtonIteration(cv_mem); - - /* If there is a convergence failure and the Jacobian-related - data appears not to be current, loop again with a call to lsetup - in which convfail=CV_FAIL_BAD_J. Otherwise return. */ - if (ier != TRY_AGAIN) return(ier); - - callSetup = TRUE; - convfail = CV_FAIL_BAD_J; - } -} - -/* - * CVNewtonIteration - * - * This routine performs the Newton iteration. If the iteration succeeds, - * it returns the value CV_SUCCESS. If not, it may signal the CVNlsNewton - * routine to call lsetup again and reattempt the iteration, by - * returning the value TRY_AGAIN. (In this case, CVNlsNewton must set - * convfail to CV_FAIL_BAD_J before calling setup again). - * Otherwise, this routine returns one of the appropriate values - * CV_LSOLVE_FAIL, CV_RHSFUNC_FAIL, CONV_FAIL, or RHSFUNC_RECVR back - * to CVNlsNewton. - */ - -static int CVNewtonIteration(CVodeMem cv_mem) -{ - int m, retval; - realtype del, delp, dcon; - N_Vector b; - - mnewt = m = 0; - - /* Initialize delp to avoid compiler warning message */ - del = delp = ZERO; - - /* Looping point for Newton iteration */ - loop { - - /* Evaluate the residual of the nonlinear system*/ - N_VLinearSum(rl1, zn[1], ONE, acor, tempv); - N_VLinearSum(gamma, ftemp, -ONE, tempv, tempv); - - /* Call the lsolve function */ - b = tempv; - retval = lsolve(cv_mem, b, ewt, y, ftemp); - nni++; - - if (retval < 0) return(CV_LSOLVE_FAIL); - - /* If lsolve had a recoverable failure and Jacobian data is - not current, signal to try the solution again */ - if (retval > 0) { - if ((!jcur) && (setupNonNull)) return(TRY_AGAIN); - else return(CONV_FAIL); - } - - /* Get WRMS norm of correction; add correction to acor and y */ - del = N_VWrmsNorm(b, ewt); - N_VLinearSum(ONE, acor, ONE, b, acor); - N_VLinearSum(ONE, zn[0], ONE, acor, y); - - /* Test for convergence. If m > 0, an estimate of the convergence - rate constant is stored in crate, and used in the test. */ - if (m > 0) { - crate = MAX(CRDOWN * crate, del/delp); - } - dcon = del * MIN(ONE, crate) / tq[4]; - - if (dcon <= ONE) { - acnrm = (m==0) ? del : N_VWrmsNorm(acor, ewt); - jcur = FALSE; - return(CV_SUCCESS); /* Nonlinear system was solved successfully */ - } - - mnewt = ++m; - - /* Stop at maxcor iterations or if iter. seems to be diverging. - If still not converged and Jacobian data is not current, - signal to try the solution again */ - if ((m == maxcor) || ((m >= 2) && (del > RDIV*delp))) { - if ((!jcur) && (setupNonNull)) return(TRY_AGAIN); - else return(CONV_FAIL); - } - - /* Save norm of correction, evaluate f, and loop again */ - delp = del; - retval = f(tn, y, ftemp, user_data); - nfe++; - if (retval < 0) return(CV_RHSFUNC_FAIL); - if (retval > 0) { - if ((!jcur) && (setupNonNull)) return(TRY_AGAIN); - else return(RHSFUNC_RECVR); - } - - } /* end loop */ -} - -/* - * CVHandleFlag - * - * This routine takes action on the return value nflag = *nflagPtr - * returned by CVNls, as follows: - * - * If CVNls succeeded in solving the nonlinear system, then - * CVHandleNFlag returns the constant DO_ERROR_TEST, which tells CVStep - * to perform the error test. - * - * If the nonlinear system was not solved successfully, then ncfn and - * ncf = *ncfPtr are incremented and Nordsieck array zn is restored. - * - * If the solution of the nonlinear system failed due to an - * unrecoverable failure by setup, we return the value CV_LSETUP_FAIL. - * - * If it failed due to an unrecoverable failure in solve, then we return - * the value CV_LSOLVE_FAIL. - * - * If it failed due to an unrecoverable failure in rhs, then we return - * the value CV_RHSFUNC_FAIL. - * - * Otherwise, a recoverable failure occurred when solving the - * nonlinear system (CVNls returned nflag == CONV_FAIL or RHSFUNC_RECVR). - * In this case, if ncf is now equal to maxncf or |h| = hmin, - * we return the value CV_CONV_FAILURE (if nflag=CONV_FAIL) or - * CV_REPTD_RHSFUNC_ERR (if nflag=RHSFUNC_RECVR). - * If not, we set *nflagPtr = PREV_CONV_FAIL and return the value - * PREDICT_AGAIN, telling CVStep to reattempt the step. - * - */ - -static int CVHandleNFlag(CVodeMem cv_mem, int *nflagPtr, realtype saved_t, - int *ncfPtr) -{ - int nflag; - - nflag = *nflagPtr; - - if (nflag == CV_SUCCESS) return(DO_ERROR_TEST); - - /* The nonlinear soln. failed; increment ncfn and restore zn */ - ncfn++; - CVRestore(cv_mem, saved_t); - - /* Return if lsetup, lsolve, or rhs failed unrecoverably */ - if (nflag == CV_LSETUP_FAIL) return(CV_LSETUP_FAIL); - if (nflag == CV_LSOLVE_FAIL) return(CV_LSOLVE_FAIL); - if (nflag == CV_RHSFUNC_FAIL) return(CV_RHSFUNC_FAIL); - - /* At this point, nflag = CONV_FAIL or RHSFUNC_RECVR; increment ncf */ - - (*ncfPtr)++; - etamax = ONE; - - /* If we had maxncf failures or |h| = hmin, - return CV_CONV_FAILURE or CV_REPTD_RHSFUNC_ERR. */ - - if ((ABS(h) <= hmin*ONEPSM) || (*ncfPtr == maxncf)) { - if (nflag == CONV_FAIL) return(CV_CONV_FAILURE); - if (nflag == RHSFUNC_RECVR) return(CV_REPTD_RHSFUNC_ERR); - } - - /* Reduce step size; return to reattempt the step */ - - eta = MAX(ETACF, hmin / ABS(h)); - *nflagPtr = PREV_CONV_FAIL; - CVRescale(cv_mem); - - return(PREDICT_AGAIN); -} - -/* - * CVRestore - * - * This routine restores the value of tn to saved_t and undoes the - * prediction. After execution of CVRestore, the Nordsieck array zn has - * the same values as before the call to CVPredict. - */ - -static void CVRestore(CVodeMem cv_mem, realtype saved_t) -{ - int j, k; - - tn = saved_t; - for (k = 1; k <= q; k++) - for (j = q; j >= k; j--) - N_VLinearSum(ONE, zn[j-1], -ONE, zn[j], zn[j-1]); -} - -/* - * CVDoErrorTest - * - * This routine performs the local error test. - * The weighted local error norm dsm is loaded into *dsmPtr, and - * the test dsm ?<= 1 is made. - * - * If the test passes, CVDoErrorTest returns CV_SUCCESS. - * - * If the test fails, we undo the step just taken (call CVRestore) and - * - * - if maxnef error test failures have occurred or if ABS(h) = hmin, - * we return CV_ERR_FAILURE. - * - * - if more than MXNEF1 error test failures have occurred, an order - * reduction is forced. If already at order 1, restart by reloading - * zn from scratch. If f() fails we return either CV_RHSFUNC_FAIL - * or CV_UNREC_RHSFUNC_ERR (no recovery is possible at this stage). - * - * - otherwise, set *nflagPtr to PREV_ERR_FAIL, and return TRY_AGAIN. - * - */ - -static booleantype CVDoErrorTest(CVodeMem cv_mem, int *nflagPtr, - realtype saved_t, int *nefPtr, realtype *dsmPtr) -{ - realtype dsm; - int retval; - - dsm = acnrm * tq[2]; - - /* If est. local error norm dsm passes test, return CV_SUCCESS */ - *dsmPtr = dsm; - if (dsm <= ONE) return(CV_SUCCESS); - - /* Test failed; increment counters, set nflag, and restore zn array */ - (*nefPtr)++; - netf++; - *nflagPtr = PREV_ERR_FAIL; - CVRestore(cv_mem, saved_t); - - /* At maxnef failures or |h| = hmin, return CV_ERR_FAILURE */ - if ((ABS(h) <= hmin*ONEPSM) || (*nefPtr == maxnef)) return(CV_ERR_FAILURE); - - /* Set etamax = 1 to prevent step size increase at end of this step */ - etamax = ONE; - - /* Set h ratio eta from dsm, rescale, and return for retry of step */ - if (*nefPtr <= MXNEF1) { - eta = ONE / (RPowerR(BIAS2*dsm,ONE/L) + ADDON); - eta = MAX(ETAMIN, MAX(eta, hmin / ABS(h))); - if (*nefPtr >= SMALL_NEF) eta = MIN(eta, ETAMXF); - CVRescale(cv_mem); - return(TRY_AGAIN); - } - - /* After MXNEF1 failures, force an order reduction and retry step */ - if (q > 1) { - eta = MAX(ETAMIN, hmin / ABS(h)); - CVAdjustOrder(cv_mem,-1); - L = q; - q--; - qwait = L; - CVRescale(cv_mem); - return(TRY_AGAIN); - } - - /* If already at order 1, restart: reload zn from scratch */ - - eta = MAX(ETAMIN, hmin / ABS(h)); - h *= eta; - next_h = h; - hscale = h; - qwait = LONG_WAIT; - nscon = 0; - - retval = f(tn, zn[0], tempv, user_data); - nfe++; - if (retval < 0) return(CV_RHSFUNC_FAIL); - if (retval > 0) return(CV_UNREC_RHSFUNC_ERR); - - N_VScale(h, tempv, zn[1]); - - return(TRY_AGAIN); -} - -/* - * ================================================================= - * Private Functions Implementation after succesful step - * ================================================================= - */ - -/* - * CVCompleteStep - * - * This routine performs various update operations when the solution - * to the nonlinear system has passed the local error test. - * We increment the step counter nst, record the values hu and qu, - * update the tau array, and apply the corrections to the zn array. - * The tau[i] are the last q values of h, with tau[1] the most recent. - * The counter qwait is decremented, and if qwait == 1 (and q < qmax) - * we save acor and tq[5] for a possible order increase. - */ - -static void CVCompleteStep(CVodeMem cv_mem) -{ - int i, j; - - nst++; - nscon++; - hu = h; - qu = q; - - for (i=q; i >= 2; i--) tau[i] = tau[i-1]; - if ((q==1) && (nst > 1)) tau[2] = tau[1]; - tau[1] = h; - - for (j=0; j <= q; j++) - N_VLinearSum(l[j], acor, ONE, zn[j], zn[j]); - qwait--; - if ((qwait == 1) && (q != qmax)) { - N_VScale(ONE, acor, zn[qmax]); - saved_tq5 = tq[5]; - indx_acor = qmax; - } -} - -/* - * CVprepareNextStep - * - * This routine handles the setting of stepsize and order for the - * next step -- hprime and qprime. Along with hprime, it sets the - * ratio eta = hprime/h. It also updates other state variables - * related to a change of step size or order. - */ - - static void CVPrepareNextStep(CVodeMem cv_mem, realtype dsm) -{ - /* If etamax = 1, defer step size or order changes */ - if (etamax == ONE) { - qwait = MAX(qwait, 2); - qprime = q; - hprime = h; - eta = ONE; - return; - } - - /* etaq is the ratio of new to old h at the current order */ - etaq = ONE /(RPowerR(BIAS2*dsm,ONE/L) + ADDON); - - /* If no order change, adjust eta and acor in CVSetEta and return */ - if (qwait != 0) { - eta = etaq; - qprime = q; - CVSetEta(cv_mem); - return; - } - - /* If qwait = 0, consider an order change. etaqm1 and etaqp1 are - the ratios of new to old h at orders q-1 and q+1, respectively. - CVChooseEta selects the largest; CVSetEta adjusts eta and acor */ - qwait = 2; - etaqm1 = CVComputeEtaqm1(cv_mem); - etaqp1 = CVComputeEtaqp1(cv_mem); - CVChooseEta(cv_mem); - CVSetEta(cv_mem); -} - -/* - * CVsetEta - * - * This routine adjusts the value of eta according to the various - * heuristic limits and the optional input hmax. It also resets - * etamax to be the estimated local error vector. - */ - -static void CVSetEta(CVodeMem cv_mem) -{ - - /* If eta below the threshhold THRESH, reject a change of step size */ - if (eta < THRESH) { - eta = ONE; - hprime = h; - } else { - /* Limit eta by etamax and hmax, then set hprime */ - eta = MIN(eta, etamax); - eta /= MAX(ONE, ABS(h)*hmax_inv*eta); - hprime = h * eta; - if (qprime < q) nscon = 0; - } - - /* Reset etamax for the next step size change, and scale acor */ -} - -/* - * CVComputeEtaqm1 - * - * This routine computes and returns the value of etaqm1 for a - * possible decrease in order by 1. - */ - -static realtype CVComputeEtaqm1(CVodeMem cv_mem) -{ - realtype ddn; - - etaqm1 = ZERO; - if (q > 1) { - ddn = N_VWrmsNorm(zn[q], ewt) * tq[1]; - etaqm1 = ONE/(RPowerR(BIAS1*ddn, ONE/q) + ADDON); - } - return(etaqm1); -} - -/* - * CVComputeEtaqp1 - * - * This routine computes and returns the value of etaqp1 for a - * possible increase in order by 1. - */ - -static realtype CVComputeEtaqp1(CVodeMem cv_mem) -{ - realtype dup, cquot; - - etaqp1 = ZERO; - if (q != qmax) { - if (saved_tq5 == ZERO) return(etaqp1); - cquot = (tq[5] / saved_tq5) * RPowerI(h/tau[2], L); - N_VLinearSum(-cquot, zn[qmax], ONE, acor, tempv); - dup = N_VWrmsNorm(tempv, ewt) * tq[3]; - etaqp1 = ONE / (RPowerR(BIAS3*dup, ONE/(L+1)) + ADDON); - } - return(etaqp1); -} - -/* - * CVChooseEta - * Given etaqm1, etaq, etaqp1 (the values of eta for qprime = - * q - 1, q, or q + 1, respectively), this routine chooses the - * maximum eta value, sets eta to that value, and sets qprime to the - * corresponding value of q. If there is a tie, the preference - * order is to (1) keep the same order, then (2) decrease the order, - * and finally (3) increase the order. If the maximum eta value - * is below the threshhold THRESH, the order is kept unchanged and - * eta is set to 1. - */ - -static void CVChooseEta(CVodeMem cv_mem) -{ - realtype etam; - - etam = MAX(etaqm1, MAX(etaq, etaqp1)); - - if (etam < THRESH) { - eta = ONE; - qprime = q; - return; - } - - if (etam == etaq) { - - eta = etaq; - qprime = q; - - } else if (etam == etaqm1) { - - eta = etaqm1; - qprime = q - 1; - - } else { - - eta = etaqp1; - qprime = q + 1; - - if (lmm == CV_BDF) { - - /* - * Store Delta_n in zn[qmax] to be used in order increase - * - * This happens at the last step of order q before an increase - * to order q+1, so it represents Delta_n in the ELTE at q+1 - */ - - N_VScale(ONE, acor, zn[qmax]); - - } - - } - -} - -/* - * CVHandleFailure - * - * This routine prints error messages for all cases of failure by - * CVHin and CVStep. It returns to CVode the value that CVode is - * to return to the user. - */ - -static int CVHandleFailure(CVodeMem cv_mem, int flag) -{ - - /* Set vector of absolute weighted local errors */ - /* - N_VProd(acor, ewt, tempv); - N_VAbs(tempv, tempv); - */ - - /* Depending on flag, print error message and return error flag */ - switch (flag) { - case CV_ERR_FAILURE: - CVProcessError(cv_mem, CV_ERR_FAILURE, "CVODE", "CVode", MSGCV_ERR_FAILS, tn, h); - break; - case CV_CONV_FAILURE: - CVProcessError(cv_mem, CV_CONV_FAILURE, "CVODE", "CVode", MSGCV_CONV_FAILS, tn, h); - break; - case CV_LSETUP_FAIL: - CVProcessError(cv_mem, CV_LSETUP_FAIL, "CVODE", "CVode", MSGCV_SETUP_FAILED, tn); - break; - case CV_LSOLVE_FAIL: - CVProcessError(cv_mem, CV_LSOLVE_FAIL, "CVODE", "CVode", MSGCV_SOLVE_FAILED, tn); - break; - case CV_RHSFUNC_FAIL: - CVProcessError(cv_mem, CV_RHSFUNC_FAIL, "CVODE", "CVode", MSGCV_RHSFUNC_FAILED, tn); - break; - case CV_UNREC_RHSFUNC_ERR: - CVProcessError(cv_mem, CV_UNREC_RHSFUNC_ERR, "CVODE", "CVode", MSGCV_RHSFUNC_UNREC, tn); - break; - case CV_REPTD_RHSFUNC_ERR: - CVProcessError(cv_mem, CV_REPTD_RHSFUNC_ERR, "CVODE", "CVode", MSGCV_RHSFUNC_REPTD, tn); - break; - case CV_RTFUNC_FAIL: - CVProcessError(cv_mem, CV_RTFUNC_FAIL, "CVODE", "CVode", MSGCV_RTFUNC_FAILED, tn); - break; - case CV_TOO_CLOSE: - CVProcessError(cv_mem, CV_TOO_CLOSE, "CVODE", "CVode", MSGCV_TOO_CLOSE); - break; - default: - return(CV_SUCCESS); - } - - return(flag); - -} - -/* - * ================================================================= - * BDF Stability Limit Detection - * ================================================================= - */ - -/* - * CVBDFStab - * - * This routine handles the BDF Stability Limit Detection Algorithm - * STALD. It is called if lmm = CV_BDF and the SLDET option is on. - * If the order is 3 or more, the required norm data is saved. - * If a decision to reduce order has not already been made, and - * enough data has been saved, CVsldet is called. If it signals - * a stability limit violation, the order is reduced, and the step - * size is reset accordingly. - */ - -void CVBDFStab(CVodeMem cv_mem) -{ - int i,k, ldflag, factorial; - realtype sq, sqm1, sqm2; - - /* If order is 3 or greater, then save scaled derivative data, - push old data down in i, then add current values to top. */ - - if (q >= 3) { - for (k = 1; k <= 3; k++) - { for (i = 5; i >= 2; i--) ssdat[i][k] = ssdat[i-1][k]; } - factorial = 1; - for (i = 1; i <= q-1; i++) factorial *= i; - sq = factorial*q*(q+1)*acnrm/MAX(tq[5],TINY); - sqm1 = factorial*q*N_VWrmsNorm(zn[q], ewt); - sqm2 = factorial*N_VWrmsNorm(zn[q-1], ewt); - ssdat[1][1] = sqm2*sqm2; - ssdat[1][2] = sqm1*sqm1; - ssdat[1][3] = sq*sq; - } - - if (qprime >= q) { - - /* If order is 3 or greater, and enough ssdat has been saved, - nscon >= q+5, then call stability limit detection routine. */ - - if ( (q >= 3) && (nscon >= q+5) ) { - ldflag = CVsldet(cv_mem); - if (ldflag > 3) { - /* A stability limit violation is indicated by - a return flag of 4, 5, or 6. - Reduce new order. */ - qprime = q-1; - eta = etaqm1; - eta = MIN(eta,etamax); - eta = eta/MAX(ONE,ABS(h)*hmax_inv*eta); - hprime = h*eta; - nor = nor + 1; - } - } - } - else { - /* Otherwise, let order increase happen, and - reset stability limit counter, nscon. */ - nscon = 0; - } -} - -/* - * CVsldet - * - * This routine detects stability limitation using stored scaled - * derivatives data. CVsldet returns the magnitude of the - * dominate characteristic root, rr. The presents of a stability - * limit is indicated by rr > "something a little less then 1.0", - * and a positive kflag. This routine should only be called if - * order is greater than or equal to 3, and data has been collected - * for 5 time steps. - * - * Returned values: - * kflag = 1 -> Found stable characteristic root, normal matrix case - * kflag = 2 -> Found stable characteristic root, quartic solution - * kflag = 3 -> Found stable characteristic root, quartic solution, - * with Newton correction - * kflag = 4 -> Found stability violation, normal matrix case - * kflag = 5 -> Found stability violation, quartic solution - * kflag = 6 -> Found stability violation, quartic solution, - * with Newton correction - * - * kflag < 0 -> No stability limitation, - * or could not compute limitation. - * - * kflag = -1 -> Min/max ratio of ssdat too small. - * kflag = -2 -> For normal matrix case, vmax > vrrt2*vrrt2 - * kflag = -3 -> For normal matrix case, The three ratios - * are inconsistent. - * kflag = -4 -> Small coefficient prevents elimination of quartics. - * kflag = -5 -> R value from quartics not consistent. - * kflag = -6 -> No corrected root passes test on qk values - * kflag = -7 -> Trouble solving for sigsq. - * kflag = -8 -> Trouble solving for B, or R via B. - * kflag = -9 -> R via sigsq[k] disagrees with R from data. - */ - -static int CVsldet(CVodeMem cv_mem) -{ - int i, k, j, it, kmin, kflag = 0; - realtype rat[5][4], rav[4], qkr[4], sigsq[4], smax[4], ssmax[4]; - realtype drr[4], rrc[4],sqmx[4], qjk[4][4], vrat[5], qc[6][4], qco[6][4]; - realtype rr, rrcut, vrrtol, vrrt2, sqtol, rrtol; - realtype smink, smaxk, sumrat, sumrsq, vmin, vmax, drrmax, adrr; - realtype tem, sqmax, saqk, qp, s, sqmaxk, saqj, sqmin; - realtype rsa, rsb, rsc, rsd, rd1a, rd1b, rd1c; - realtype rd2a, rd2b, rd3a, cest1, corr1; - realtype ratp, ratm, qfac1, qfac2, bb, rrb; - - /* The following are cutoffs and tolerances used by this routine */ - - rrcut = RCONST(0.98); - vrrtol = RCONST(1.0e-4); - vrrt2 = RCONST(5.0e-4); - sqtol = RCONST(1.0e-3); - rrtol = RCONST(1.0e-2); - - rr = ZERO; - - /* Index k corresponds to the degree of the interpolating polynomial. */ - /* k = 1 -> q-1 */ - /* k = 2 -> q */ - /* k = 3 -> q+1 */ - - /* Index i is a backward-in-time index, i = 1 -> current time, */ - /* i = 2 -> previous step, etc */ - - /* get maxima, minima, and variances, and form quartic coefficients */ - - for (k=1; k<=3; k++) { - smink = ssdat[1][k]; - smaxk = ZERO; - - for (i=1; i<=5; i++) { - smink = MIN(smink,ssdat[i][k]); - smaxk = MAX(smaxk,ssdat[i][k]); - } - - if (smink < TINY*smaxk) { - kflag = -1; - return(kflag); - } - smax[k] = smaxk; - ssmax[k] = smaxk*smaxk; - - sumrat = ZERO; - sumrsq = ZERO; - for (i=1; i<=4; i++) { - rat[i][k] = ssdat[i][k]/ssdat[i+1][k]; - sumrat = sumrat + rat[i][k]; - sumrsq = sumrsq + rat[i][k]*rat[i][k]; - } - rav[k] = FOURTH*sumrat; - vrat[k] = ABS(FOURTH*sumrsq - rav[k]*rav[k]); - - qc[5][k] = ssdat[1][k]*ssdat[3][k] - ssdat[2][k]*ssdat[2][k]; - qc[4][k] = ssdat[2][k]*ssdat[3][k] - ssdat[1][k]*ssdat[4][k]; - qc[3][k] = ZERO; - qc[2][k] = ssdat[2][k]*ssdat[5][k] - ssdat[3][k]*ssdat[4][k]; - qc[1][k] = ssdat[4][k]*ssdat[4][k] - ssdat[3][k]*ssdat[5][k]; - - for (i=1; i<=5; i++) { - qco[i][k] = qc[i][k]; - } - } /* End of k loop */ - - /* Isolate normal or nearly-normal matrix case. Three quartic will - have common or nearly-common roots in this case. - Return a kflag = 1 if this procedure works. If three root - differ more than vrrt2, return error kflag = -3. */ - - vmin = MIN(vrat[1],MIN(vrat[2],vrat[3])); - vmax = MAX(vrat[1],MAX(vrat[2],vrat[3])); - - if(vmin < vrrtol*vrrtol) { - if (vmax > vrrt2*vrrt2) { - kflag = -2; - return(kflag); - } else { - rr = (rav[1] + rav[2] + rav[3])/THREE; - - drrmax = ZERO; - for(k = 1;k<=3;k++) { - adrr = ABS(rav[k] - rr); - drrmax = MAX(drrmax, adrr); - } - if (drrmax > vrrt2) { - kflag = -3; - } - - kflag = 1; - - /* can compute charactistic root, drop to next section */ - - } - } else { - - /* use the quartics to get rr. */ - - if (ABS(qco[1][1]) < TINY*ssmax[1]) { - kflag = -4; - return(kflag); - } - - tem = qco[1][2]/qco[1][1]; - for(i=2; i<=5; i++) { - qco[i][2] = qco[i][2] - tem*qco[i][1]; - } - - qco[1][2] = ZERO; - tem = qco[1][3]/qco[1][1]; - for(i=2; i<=5; i++) { - qco[i][3] = qco[i][3] - tem*qco[i][1]; - } - qco[1][3] = ZERO; - - if (ABS(qco[2][2]) < TINY*ssmax[2]) { - kflag = -4; - return(kflag); - } - - tem = qco[2][3]/qco[2][2]; - for(i=3; i<=5; i++) { - qco[i][3] = qco[i][3] - tem*qco[i][2]; - } - - if (ABS(qco[4][3]) < TINY*ssmax[3]) { - kflag = -4; - return(kflag); - } - - rr = -qco[5][3]/qco[4][3]; - - if (rr < TINY || rr > HUN) { - kflag = -5; - return(kflag); - } - - for(k=1; k<=3; k++) { - qkr[k] = qc[5][k] + rr*(qc[4][k] + rr*rr*(qc[2][k] + rr*qc[1][k])); - } - - sqmax = ZERO; - for(k=1; k<=3; k++) { - saqk = ABS(qkr[k])/ssmax[k]; - if (saqk > sqmax) sqmax = saqk; - } - - if (sqmax < sqtol) { - kflag = 2; - - /* can compute charactistic root, drop to "given rr,etc" */ - - } else { - - /* do Newton corrections to improve rr. */ - - for(it=1; it<=3; it++) { - for(k=1; k<=3; k++) { - qp = qc[4][k] + rr*rr*(THREE*qc[2][k] + rr*FOUR*qc[1][k]); - drr[k] = ZERO; - if (ABS(qp) > TINY*ssmax[k]) drr[k] = -qkr[k]/qp; - rrc[k] = rr + drr[k]; - } - - for(k=1; k<=3; k++) { - s = rrc[k]; - sqmaxk = ZERO; - for(j=1; j<=3; j++) { - qjk[j][k] = qc[5][j] + s*(qc[4][j] + - s*s*(qc[2][j] + s*qc[1][j])); - saqj = ABS(qjk[j][k])/ssmax[j]; - if (saqj > sqmaxk) sqmaxk = saqj; - } - sqmx[k] = sqmaxk; - } - - sqmin = sqmx[1]; kmin = 1; - for(k=2; k<=3; k++) { - if (sqmx[k] < sqmin) { - kmin = k; - sqmin = sqmx[k]; - } - } - rr = rrc[kmin]; - - if (sqmin < sqtol) { - kflag = 3; - /* can compute charactistic root */ - /* break out of Newton correction loop and drop to "given rr,etc" */ - break; - } else { - for(j=1; j<=3; j++) { - qkr[j] = qjk[j][kmin]; - } - } - } /* end of Newton correction loop */ - - if (sqmin > sqtol) { - kflag = -6; - return(kflag); - } - } /* end of if (sqmax < sqtol) else */ - } /* end of if(vmin < vrrtol*vrrtol) else, quartics to get rr. */ - - /* given rr, find sigsq[k] and verify rr. */ - /* All positive kflag drop to this section */ - - for(k=1; k<=3; k++) { - rsa = ssdat[1][k]; - rsb = ssdat[2][k]*rr; - rsc = ssdat[3][k]*rr*rr; - rsd = ssdat[4][k]*rr*rr*rr; - rd1a = rsa - rsb; - rd1b = rsb - rsc; - rd1c = rsc - rsd; - rd2a = rd1a - rd1b; - rd2b = rd1b - rd1c; - rd3a = rd2a - rd2b; - - if (ABS(rd1b) < TINY*smax[k]) { - kflag = -7; - return(kflag); - } - - cest1 = -rd3a/rd1b; - if (cest1 < TINY || cest1 > FOUR) { - kflag = -7; - return(kflag); - } - corr1 = (rd2b/cest1)/(rr*rr); - sigsq[k] = ssdat[3][k] + corr1; - } - - if (sigsq[2] < TINY) { - kflag = -8; - return(kflag); - } - - ratp = sigsq[3]/sigsq[2]; - ratm = sigsq[1]/sigsq[2]; - qfac1 = FOURTH*(q*q - ONE); - qfac2 = TWO/(q - ONE); - bb = ratp*ratm - ONE - qfac1*ratp; - tem = ONE - qfac2*bb; - - if (ABS(tem) < TINY) { - kflag = -8; - return(kflag); - } - - rrb = ONE/tem; - - if (ABS(rrb - rr) > rrtol) { - kflag = -9; - return(kflag); - } - - /* Check to see if rr is above cutoff rrcut */ - if (rr > rrcut) { - if (kflag == 1) kflag = 4; - if (kflag == 2) kflag = 5; - if (kflag == 3) kflag = 6; - } - - /* All positive kflag returned at this point */ - - return(kflag); - -} - -/* - * ================================================================= - * Root finding - * ================================================================= - */ - -/*-----------------------------------------------------------------*/ - -/* - * CVRcheck1 - * - * This routine completes the initialization of rootfinding memory - * information, and checks whether g has a zero both at and very near - * the initial point of the IVP. - * - * This routine returns an int equal to: - * CV_RTFUNC_FAIL = -12 if the g function failed, or - * CV_SUCCESS = 0 otherwise. - */ - -static int CVRcheck1(CVodeMem cv_mem) -{ - int i, retval; - realtype smallh, hratio; - booleantype zroot; - - for (i = 0; i < nrtfn; i++) iroots[i] = 0; - tlo = tn; - ttol = (ABS(tn) + ABS(h))*uround*HUN; - - /* Evaluate g at initial t and check for zero values. */ - retval = gfun(tlo, zn[0], glo, user_data); - nge = 1; - if (retval != 0) return(CV_RTFUNC_FAIL); - - zroot = FALSE; - for (i = 0; i < nrtfn; i++) { - if (ABS(glo[i]) == ZERO) { - zroot = TRUE; - gactive[i] = FALSE; - } - } - if (!zroot) return(CV_SUCCESS); - - /* Some g_i is zero at t0; look at g at t0+(small increment). */ - hratio = MAX(ttol/ABS(h), TENTH); - smallh = hratio*h; - tlo += smallh; - N_VLinearSum(ONE, zn[0], hratio, zn[1], y); - retval = gfun(tlo, y, glo, user_data); - nge++; - if (retval != 0) return(CV_RTFUNC_FAIL); - - /* We check now only the components of g which were exactly 0.0 at t0 - * to see if we can 'activate' them. */ - - for (i = 0; i < nrtfn; i++) { - if (!gactive[i] && ABS(glo[i]) != ZERO) { - gactive[i] = TRUE; - - } - } - - return(CV_SUCCESS); -} - -/* - * CVRcheck2 - * - * This routine checks for exact zeros of g at the last root found, - * if the last return was a root. It then checks for a close - * pair of zeros (an error condition), and for a new root at a - * nearby point. The left endpoint (tlo) of the search interval - * is adjusted if necessary to assure that all g_i are nonzero - * there, before returning to do a root search in the interval. - * - * On entry, tlo = tretlast is the last value of tret returned by - * CVode. This may be the previous tn, the previous tout value, or - * the last root location. - * - * This routine returns an int equal to: - * CV_RTFUNC_FAIL = -12 if the g function failed, or - * CLOSERT = 3 if a close pair of zeros was found, or - * RTFOUND = 1 if a new zero of g was found near tlo, or - * CV_SUCCESS = 0 otherwise. - */ - -static int CVRcheck2(CVodeMem cv_mem) -{ - int i, retval; - realtype smallh, hratio; - booleantype zroot; - - if (irfnd == 0) return(CV_SUCCESS); - - (void) CVodeGetDky(cv_mem, tlo, 0, y); - retval = gfun(tlo, y, glo, user_data); - nge++; - if (retval != 0) return(CV_RTFUNC_FAIL); - - zroot = FALSE; - for (i = 0; i < nrtfn; i++) iroots[i] = 0; - for (i = 0; i < nrtfn; i++) { - if (!gactive[i]) continue; - if (ABS(glo[i]) == ZERO) { - zroot = TRUE; - iroots[i] = 1; - } - } - if (!zroot) return(CV_SUCCESS); - - /* One or more g_i has a zero at tlo. Check g at tlo+smallh. */ - ttol = (ABS(tn) + ABS(h))*uround*HUN; - smallh = (h > ZERO) ? ttol : -ttol; - tlo += smallh; - if ( (tlo - tn)*h >= ZERO) { - hratio = smallh/h; - N_VLinearSum(ONE, y, hratio, zn[1], y); - } else { - (void) CVodeGetDky(cv_mem, tlo, 0, y); - } - retval = gfun(tlo, y, glo, user_data); - nge++; - if (retval != 0) return(CV_RTFUNC_FAIL); - - zroot = FALSE; - for (i = 0; i < nrtfn; i++) { - if (ABS(glo[i]) == ZERO) { - if (!gactive[i]) continue; - if (iroots[i] == 1) return(CLOSERT); - zroot = TRUE; - iroots[i] = 1; - } - } - if (zroot) return(RTFOUND); - return(CV_SUCCESS); - -} - -/* - * CVRcheck3 - * - * This routine interfaces to CVRootfind to look for a root of g - * between tlo and either tn or tout, whichever comes first. - * Only roots beyond tlo in the direction of integration are sought. - * - * This routine returns an int equal to: - * CV_RTFUNC_FAIL = -12 if the g function failed, or - * RTFOUND = 1 if a root of g was found, or - * CV_SUCCESS = 0 otherwise. - */ - -static int CVRcheck3(CVodeMem cv_mem) -{ - int i, retval, ier; - - /* Set thi = tn or tout, whichever comes first; set y = y(thi). */ - if (taskc == CV_ONE_STEP) { - thi = tn; - N_VScale(ONE, zn[0], y); - } - if (taskc == CV_NORMAL) { - if ( (toutc - tn)*h >= ZERO) { - thi = tn; - N_VScale(ONE, zn[0], y); - } else { - thi = toutc; - (void) CVodeGetDky(cv_mem, thi, 0, y); - } - } - - /* Set ghi = g(thi) and call CVRootfind to search (tlo,thi) for roots. */ - retval = gfun(thi, y, ghi, user_data); - nge++; - if (retval != 0) return(CV_RTFUNC_FAIL); - - ttol = (ABS(tn) + ABS(h))*uround*HUN; - ier = CVRootfind(cv_mem); - if (ier == CV_RTFUNC_FAIL) return(CV_RTFUNC_FAIL); - for(i=0; i 0, search for roots of g_i only if - * g_i is increasing; if rootdir[i] < 0, search for - * roots of g_i only if g_i is decreasing; otherwise - * always search for roots of g_i. - * - * gactive = array specifying whether a component of g should - * or should not be monitored. gactive[i] is initially - * set to TRUE for all i=0,...,nrtfn-1, but it may be - * reset to FALSE if at the first step g[i] is 0.0 - * both at the I.C. and at a small perturbation of them. - * gactive[i] is then set back on TRUE only after the - * corresponding g function moves away from 0.0. - * - * nge = cumulative counter for gfun calls. - * - * ttol = a convergence tolerance for trout. Input only. - * When a root at trout is found, it is located only to - * within a tolerance of ttol. Typically, ttol should - * be set to a value on the order of - * 100 * UROUND * max (ABS(tlo), ABS(thi)) - * where UROUND is the unit roundoff of the machine. - * - * tlo, thi = endpoints of the interval in which roots are sought. - * On input, and must be distinct, but tlo - thi may - * be of either sign. The direction of integration is - * assumed to be from tlo to thi. On return, tlo and thi - * are the endpoints of the final relevant interval. - * - * glo, ghi = arrays of length nrtfn containing the vectors g(tlo) - * and g(thi) respectively. Input and output. On input, - * none of the glo[i] should be zero. - * - * trout = root location, if a root was found, or thi if not. - * Output only. If a root was found other than an exact - * zero of g, trout is the endpoint thi of the final - * interval bracketing the root, with size at most ttol. - * - * grout = array of length nrtfn containing g(trout) on return. - * - * iroots = int array of length nrtfn with root information. - * Output only. If a root was found, iroots indicates - * which components g_i have a root at trout. For - * i = 0, ..., nrtfn-1, iroots[i] = 1 if g_i has a root - * and g_i is increasing, iroots[i] = -1 if g_i has a - * root and g_i is decreasing, and iroots[i] = 0 if g_i - * has no roots or g_i varies in the direction opposite - * to that indicated by rootdir[i]. - * - * This routine returns an int equal to: - * CV_RTFUNC_FAIL = -12 if the g function failed, or - * RTFOUND = 1 if a root of g was found, or - * CV_SUCCESS = 0 otherwise. - */ - -static int CVRootfind(CVodeMem cv_mem) -{ - realtype alpha, tmid, gfrac, maxfrac, fracint, fracsub; - int i, retval, imax, side, sideprev; - booleantype zroot, sgnchg; - - imax = 0; - - /* First check for change in sign in ghi or for a zero in ghi. */ - maxfrac = ZERO; - zroot = FALSE; - sgnchg = FALSE; - for (i = 0; i < nrtfn; i++) { - if(!gactive[i]) continue; - if (ABS(ghi[i]) == ZERO) { - if(rootdir[i]*glo[i] <= ZERO) { - zroot = TRUE; - } - } else { - if ( (glo[i]*ghi[i] < ZERO) && (rootdir[i]*glo[i] <= ZERO) ) { - gfrac = ABS(ghi[i]/(ghi[i] - glo[i])); - if (gfrac > maxfrac) { - sgnchg = TRUE; - maxfrac = gfrac; - imax = i; - } - } - } - } - - /* If no sign change was found, reset trout and grout. Then return - CV_SUCCESS if no zero was found, or set iroots and return RTFOUND. */ - if (!sgnchg) { - trout = thi; - for (i = 0; i < nrtfn; i++) grout[i] = ghi[i]; - if (!zroot) return(CV_SUCCESS); - for (i = 0; i < nrtfn; i++) { - iroots[i] = 0; - if(!gactive[i]) continue; - if (ABS(ghi[i]) == ZERO) iroots[i] = glo[i] > 0 ? -1:1; - } - return(RTFOUND); - } - - /* Initialize alpha to avoid compiler warning */ - alpha = ONE; - - /* A sign change was found. Loop to locate nearest root. */ - - side = 0; sideprev = -1; - loop { /* Looping point */ - - /* Set weight alpha. - On the first two passes, set alpha = 1. Thereafter, reset alpha - according to the side (low vs high) of the subinterval in which - the sign change was found in the previous two passes. - If the sides were opposite, set alpha = 1. - If the sides were the same, then double alpha (if high side), - or halve alpha (if low side). - The next guess tmid is the secant method value if alpha = 1, but - is closer to tlo if alpha < 1, and closer to thi if alpha > 1. */ - - if (sideprev == side) { - alpha = (side == 2) ? alpha*TWO : alpha*HALF; - } else { - alpha = ONE; - } - - /* Set next root approximation tmid and get g(tmid). - If tmid is too close to tlo or thi, adjust it inward, - by a fractional distance that is between 0.1 and 0.5. */ - tmid = thi - (thi - tlo)*ghi[imax]/(ghi[imax] - alpha*glo[imax]); - if (ABS(tmid - tlo) < HALF*ttol) { - fracint = ABS(thi - tlo)/ttol; - fracsub = (fracint > FIVE) ? TENTH : HALF/fracint; - tmid = tlo + fracsub*(thi - tlo); - } - if (ABS(thi - tmid) < HALF*ttol) { - fracint = ABS(thi - tlo)/ttol; - fracsub = (fracint > FIVE) ? TENTH : HALF/fracint; - tmid = thi - fracsub*(thi - tlo); - } - - (void) CVodeGetDky(cv_mem, tmid, 0, y); - retval = gfun(tmid, y, grout, user_data); - nge++; - if (retval != 0) return(CV_RTFUNC_FAIL); - - /* Check to see in which subinterval g changes sign, and reset imax. - Set side = 1 if sign change is on low side, or 2 if on high side. */ - maxfrac = ZERO; - zroot = FALSE; - sgnchg = FALSE; - sideprev = side; - for (i = 0; i < nrtfn; i++) { - if(!gactive[i]) continue; - if (ABS(grout[i]) == ZERO) { - if(rootdir[i]*glo[i] <= ZERO) { - zroot = TRUE; - } - } else { - if ( (glo[i]*grout[i] < ZERO) && (rootdir[i]*glo[i] <= ZERO) ) { - gfrac = ABS(grout[i]/(grout[i] - glo[i])); - if (gfrac > maxfrac) { - sgnchg = TRUE; - maxfrac = gfrac; - imax = i; - } - } - } - } - if (sgnchg) { - /* Sign change found in (tlo,tmid); replace thi with tmid. */ - thi = tmid; - for (i = 0; i < nrtfn; i++) ghi[i] = grout[i]; - side = 1; - /* Stop at root thi if converged; otherwise loop. */ - if (ABS(thi - tlo) <= ttol) break; - continue; /* Return to looping point. */ - } - - if (zroot) { - /* No sign change in (tlo,tmid), but g = 0 at tmid; return root tmid. */ - thi = tmid; - for (i = 0; i < nrtfn; i++) ghi[i] = grout[i]; - break; - } - - /* No sign change in (tlo,tmid), and no zero at tmid. - Sign change must be in (tmid,thi). Replace tlo with tmid. */ - tlo = tmid; - for (i = 0; i < nrtfn; i++) glo[i] = grout[i]; - side = 2; - /* Stop at root thi if converged; otherwise loop back. */ - if (ABS(thi - tlo) <= ttol) break; - - } /* End of root-search loop */ - - /* Reset trout and grout, set iroots, and return RTFOUND. */ - trout = thi; - for (i = 0; i < nrtfn; i++) { - grout[i] = ghi[i]; - iroots[i] = 0; - if(!gactive[i]) continue; - if ( (ABS(ghi[i]) == ZERO) && (rootdir[i]*glo[i] <= ZERO) ) - iroots[i] = glo[i] > 0 ? -1:1; - if ( (glo[i]*ghi[i] < ZERO) && (rootdir[i]*glo[i] <= ZERO) ) - iroots[i] = glo[i] > 0 ? -1:1; - } - return(RTFOUND); -} - -/* - * ================================================================= - * Internal EWT function - * ================================================================= - */ - -/* - * CVEwtSet - * - * This routine is responsible for setting the error weight vector ewt, - * according to tol_type, as follows: - * - * (1) ewt[i] = 1 / (reltol * ABS(ycur[i]) + *abstol), i=0,...,neq-1 - * if tol_type = CV_SS - * (2) ewt[i] = 1 / (reltol * ABS(ycur[i]) + abstol[i]), i=0,...,neq-1 - * if tol_type = CV_SV - * - * CVEwtSet returns 0 if ewt is successfully set as above to a - * positive vector and -1 otherwise. In the latter case, ewt is - * considered undefined. - * - * All the real work is done in the routines CVEwtSetSS, CVEwtSetSV. - */ - -int CVEwtSet(N_Vector ycur, N_Vector weight, void *data) -{ - CVodeMem cv_mem; - int flag = 0; - - /* data points to cv_mem here */ - - cv_mem = (CVodeMem) data; - - switch(itol) { - case CV_SS: - flag = CVEwtSetSS(cv_mem, ycur, weight); - break; - case CV_SV: - flag = CVEwtSetSV(cv_mem, ycur, weight); - break; - } - - return(flag); -} - -/* - * CVEwtSetSS - * - * This routine sets ewt as decribed above in the case tol_type = CV_SS. - * It tests for non-positive components before inverting. CVEwtSetSS - * returns 0 if ewt is successfully set to a positive vector - * and -1 otherwise. In the latter case, ewt is considered undefined. - */ - -static int CVEwtSetSS(CVodeMem cv_mem, N_Vector ycur, N_Vector weight) -{ - N_VAbs(ycur, tempv); - N_VScale(reltol, tempv, tempv); - N_VAddConst(tempv, Sabstol, tempv); - if (N_VMin(tempv) <= ZERO) return(-1); - N_VInv(tempv, weight); - return(0); -} - -/* - * CVEwtSetSV - * - * This routine sets ewt as decribed above in the case tol_type = CV_SV. - * It tests for non-positive components before inverting. CVEwtSetSV - * returns 0 if ewt is successfully set to a positive vector - * and -1 otherwise. In the latter case, ewt is considered undefined. - */ - -static int CVEwtSetSV(CVodeMem cv_mem, N_Vector ycur, N_Vector weight) -{ - N_VAbs(ycur, tempv); - N_VLinearSum(reltol, tempv, ONE, Vabstol, tempv); - if (N_VMin(tempv) <= ZERO) return(-1); - N_VInv(tempv, weight); - return(0); -} - -/* - * ================================================================= - * CVODE Error Handling function - * ================================================================= - */ - -/* - * CVProcessError is a high level error handling function - * - if cv_mem==NULL it prints the error message to stderr - * - otherwise, it sets-up and calls the error hadling function - * pointed to by cv_ehfun - */ - -#define ehfun (cv_mem->cv_ehfun) -#define eh_data (cv_mem->cv_eh_data) - -void CVProcessError(CVodeMem cv_mem, - int error_code, const char *module, const char *fname, - const char *msgfmt, ...) -{ - va_list ap; - char msg[256]; - - /* Initialize the argument pointer variable - (msgfmt is the last required argument to CVProcessError) */ - - va_start(ap, msgfmt); - - if (cv_mem == NULL) { /* We write to stderr */ - -#ifndef NO_FPRINTF_OUTPUT - fprintf(stderr, "\n[%s ERROR] %s\n ", module, fname); - fprintf(stderr, msgfmt); - fprintf(stderr, "\n\n"); -#endif - - } else { /* We can call ehfun */ - - /* Compose the message */ - - vsprintf(msg, msgfmt, ap); - - /* Call ehfun */ - - ehfun(error_code, module, fname, msg, eh_data); - - } - - /* Finalize argument processing */ - - va_end(ap); - - return; - -} - -/* CVErrHandler is the default error handling function. - It sends the error message to the stream pointed to by cv_errfp */ - -#define errfp (cv_mem->cv_errfp) - -void CVErrHandler(int error_code, const char *module, - const char *function, char *msg, void *data) -{ - CVodeMem cv_mem; - char err_type[10]; - - /* data points to cv_mem here */ - - cv_mem = (CVodeMem) data; - - if (error_code == CV_WARNING) - sprintf(err_type,"WARNING"); - else - sprintf(err_type,"ERROR"); - -#ifndef NO_FPRINTF_OUTPUT - if (errfp!=NULL) { - fprintf(errfp,"\n[%s %s] %s\n",module,err_type,function); - fprintf(errfp," %s\n\n",msg); - } -#endif - - return; -} diff --git a/src/amuse/community/secularmultiple/src/cvode/cvode.h b/src/amuse/community/secularmultiple/src/cvode/cvode.h deleted file mode 100755 index 4fefc1686f..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/cvode.h +++ /dev/null @@ -1,790 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.12 $ - * $Date: 2007/11/26 16:19:58 $ - * ----------------------------------------------------------------- - * Programmer(s): Scott D. Cohen, Alan C. Hindmarsh, Radu Serban - * and Dan Shumaker @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the interface file for the main CVODE integrator. - * ----------------------------------------------------------------- - * - * CVODE is used to solve numerically the ordinary initial value - * problem: - * - * y' = f(t,y), - * y(t0) = y0, - * - * where t0, y0 in R^N, and f: R x R^N -> R^N are given. - * - * ----------------------------------------------------------------- - */ - -#ifndef _CVODE_H -#define _CVODE_H - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -#include - -#include "sundials_nvector.h" - -/* - * ================================================================= - * C V O D E C O N S T A N T S - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * Enumerations for inputs to CVodeCreate and CVode. - * ----------------------------------------------------------------- - * Symbolic constants for the lmm and iter parameters to CVodeCreate - * and the input parameter itask to CVode, are given below. - * - * lmm: The user of the CVODE package specifies whether to use the - * CV_ADAMS (Adams-Moulton) or CV_BDF (Backward Differentiation - * Formula) linear multistep method. The BDF method is - * recommended for stiff problems, and the CV_ADAMS method is - * recommended for nonstiff problems. - * - * iter: At each internal time step, a nonlinear equation must - * be solved. The user can specify either CV_FUNCTIONAL - * iteration, which does not require linear algebra, or a - * CV_NEWTON iteration, which requires the solution of linear - * systems. In the CV_NEWTON case, the user also specifies a - * CVODE linear solver. CV_NEWTON is recommended in case of - * stiff problems. - * - * itask: The itask input parameter to CVode indicates the job - * of the solver for the next user step. The CV_NORMAL - * itask is to have the solver take internal steps until - * it has reached or just passed the user specified tout - * parameter. The solver then interpolates in order to - * return an approximate value of y(tout). The CV_ONE_STEP - * option tells the solver to just take one internal step - * and return the solution at the point reached by that step. - * ----------------------------------------------------------------- - */ - -/* lmm */ -#define CV_ADAMS 1 -#define CV_BDF 2 - -/* iter */ -#define CV_FUNCTIONAL 1 -#define CV_NEWTON 2 - -/* itask */ -#define CV_NORMAL 1 -#define CV_ONE_STEP 2 - -/* - * ---------------------------------------- - * CVODE return flags - * ---------------------------------------- - */ - -#define CV_SUCCESS 0 -#define CV_TSTOP_RETURN 1 -#define CV_ROOT_RETURN 2 - -#define CV_WARNING 99 - -#define CV_TOO_MUCH_WORK -1 -#define CV_TOO_MUCH_ACC -2 -#define CV_ERR_FAILURE -3 -#define CV_CONV_FAILURE -4 - -#define CV_LINIT_FAIL -5 -#define CV_LSETUP_FAIL -6 -#define CV_LSOLVE_FAIL -7 -#define CV_RHSFUNC_FAIL -8 -#define CV_FIRST_RHSFUNC_ERR -9 -#define CV_REPTD_RHSFUNC_ERR -10 -#define CV_UNREC_RHSFUNC_ERR -11 -#define CV_RTFUNC_FAIL -12 - -#define CV_MEM_FAIL -20 -#define CV_MEM_NULL -21 -#define CV_ILL_INPUT -22 -#define CV_NO_MALLOC -23 -#define CV_BAD_K -24 -#define CV_BAD_T -25 -#define CV_BAD_DKY -26 -#define CV_TOO_CLOSE -27 - -/* - * ================================================================= - * F U N C T I O N T Y P E S - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * Type : CVRhsFn - * ----------------------------------------------------------------- - * The f function which defines the right hand side of the ODE - * system y' = f(t,y) must have type CVRhsFn. - * f takes as input the independent variable value t, and the - * dependent variable vector y. It stores the result of f(t,y) - * in the vector ydot. The y and ydot arguments are of type - * N_Vector. - * (Allocation of memory for ydot is handled within CVODE) - * The user_data parameter is the same as the user_data - * parameter set by the user through the CVodeSetUserData routine. - * This user-supplied pointer is passed to the user's f function - * every time it is called. - * - * A CVRhsFn should return 0 if successful, a negative value if - * an unrecoverable error occured, and a positive value if a - * recoverable error (e.g. invalid y values) occured. - * If an unrecoverable occured, the integration is halted. - * If a recoverable error occured, then (in most cases) CVODE - * will try to correct and retry. - * ----------------------------------------------------------------- - */ - -typedef int (*CVRhsFn)(realtype t, N_Vector y, - N_Vector ydot, void *user_data); - -/* - * ----------------------------------------------------------------- - * Type : CVRootFn - * ----------------------------------------------------------------- - * A function g, which defines a set of functions g_i(t,y) whose - * roots are sought during the integration, must have type CVRootFn. - * The function g takes as input the independent variable value - * t, and the dependent variable vector y. It stores the nrtfn - * values g_i(t,y) in the realtype array gout. - * (Allocation of memory for gout is handled within CVODE.) - * The user_data parameter is the same as that passed by the user - * to the CVodeSetUserData routine. This user-supplied pointer is - * passed to the user's g function every time it is called. - * - * A CVRootFn should return 0 if successful or a non-zero value - * if an error occured (in which case the integration will be halted). - * ----------------------------------------------------------------- - */ - -typedef int (*CVRootFn)(realtype t, N_Vector y, realtype *gout, void *user_data); - -/* - * ----------------------------------------------------------------- - * Type : CVEwtFn - * ----------------------------------------------------------------- - * A function e, which sets the error weight vector ewt, must have - * type CVEwtFn. - * The function e takes as input the current dependent variable y. - * It must set the vector of error weights used in the WRMS norm: - * - * ||y||_WRMS = sqrt [ 1/N * sum ( ewt_i * y_i)^2 ] - * - * Typically, the vector ewt has components: - * - * ewt_i = 1 / (reltol * |y_i| + abstol_i) - * - * The user_data parameter is the same as that passed by the user - * to the CVodeSetUserData routine. This user-supplied pointer is - * passed to the user's e function every time it is called. - * A CVEwtFn e must return 0 if the error weight vector has been - * successfuly set and a non-zero value otherwise. - * ----------------------------------------------------------------- - */ - -typedef int (*CVEwtFn)(N_Vector y, N_Vector ewt, void *user_data); - -/* - * ----------------------------------------------------------------- - * Type : CVErrHandlerFn - * ----------------------------------------------------------------- - * A function eh, which handles error messages, must have type - * CVErrHandlerFn. - * The function eh takes as input the error code, the name of the - * module reporting the error, the error message, and a pointer to - * user data, the same as that passed to CVodeSetUserData. - * - * All error codes are negative, except CV_WARNING which indicates - * a warning (the solver continues). - * - * A CVErrHandlerFn has no return value. - * ----------------------------------------------------------------- - */ - -typedef void (*CVErrHandlerFn)(int error_code, - const char *module, const char *function, - char *msg, void *user_data); - -/* - * ================================================================= - * U S E R - C A L L A B L E R O U T I N E S - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * Function : CVodeCreate - * ----------------------------------------------------------------- - * CVodeCreate creates an internal memory block for a problem to - * be solved by CVODE. - * - * lmm is the type of linear multistep method to be used. - * The legal values are CV_ADAMS and CV_BDF (see previous - * description). - * - * iter is the type of iteration used to solve the nonlinear - * system that arises during each internal time step. - * The legal values are CV_FUNCTIONAL and CV_NEWTON. - * - * If successful, CVodeCreate returns a pointer to initialized - * problem memory. This pointer should be passed to CVodeInit. - * If an initialization error occurs, CVodeCreate prints an error - * message to standard err and returns NULL. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void *CVodeCreate(int lmm, int iter); - -/* - * ----------------------------------------------------------------- - * Integrator optional input specification functions - * ----------------------------------------------------------------- - * The following functions can be called to set optional inputs - * to values other than the defaults given below: - * - * Function | Optional input / [ default value ] - * ----------------------------------------------------------------- - * | - * CVodeSetErrHandlerFn | user-provided ErrHandler function. - * | [internal] - * | - * CVodeSetErrFile | the file pointer for an error file - * | where all CVODE warning and error - * | messages will be written if the default - * | internal error handling function is used. - * | This parameter can be stdout (standard - * | output), stderr (standard error), or a - * | file pointer (corresponding to a user - * | error file opened for writing) returned - * | by fopen. - * | If not called, then all messages will - * | be written to the standard error stream. - * | [stderr] - * | - * CVodeSetUserData | a pointer to user data that will be - * | passed to the user's f function every - * | time f is called. - * | [NULL] - * | - * CVodeSetMaxOrd | maximum lmm order to be used by the - * | solver. - * | [12 for Adams , 5 for BDF] - * | - * CVodeSetMaxNumSteps | maximum number of internal steps to be - * | taken by the solver in its attempt to - * | reach tout. - * | [500] - * | - * CVodeSetMaxHnilWarns | maximum number of warning messages - * | issued by the solver that t+h==t on the - * | next internal step. A value of -1 means - * | no such messages are issued. - * | [10] - * | - * CVodeSetStabLimDet | flag to turn on/off stability limit - * | detection (TRUE = on, FALSE = off). - * | When BDF is used and order is 3 or - * | greater, CVsldet is called to detect - * | stability limit. If limit is detected, - * | the order is reduced. - * | [FALSE] - * | - * CVodeSetInitStep | initial step size. - * | [estimated by CVODE] - * | - * CVodeSetMinStep | minimum absolute value of step size - * | allowed. - * | [0.0] - * | - * CVodeSetMaxStep | maximum absolute value of step size - * | allowed. - * | [infinity] - * | - * CVodeSetStopTime | the independent variable value past - * | which the solution is not to proceed. - * | [infinity] - * | - * CVodeSetMaxErrTestFails | Maximum number of error test failures - * | in attempting one step. - * | [7] - * | - * CVodeSetMaxNonlinIters | Maximum number of nonlinear solver - * | iterations at one solution. - * | [3] - * | - * CVodeSetMaxConvFails | Maximum number of convergence failures - * | allowed in attempting one step. - * | [10] - * | - * CVodeSetNonlinConvCoef | Coefficient in the nonlinear - * | convergence test. - * | [0.1] - * | - * ----------------------------------------------------------------- - * | - * CVodeSetIterType | Changes the current nonlinear iteration - * | type. - * | [set by CVodecreate] - * | - * ----------------------------------------------------------------- - * | - * CVodeSetRootDirection | Specifies the direction of zero - * | crossings to be monitored - * | [both directions] - * | - * CVodeSetNoInactiveRootWarn | disable warning about possible - * | g==0 at beginning of integration - * | - * ----------------------------------------------------------------- - - * ----------------------------------------------------------------- - * Return flag: - * CV_SUCCESS if successful - * CV_MEM_NULL if the cvode memory is NULL - * CV_ILL_INPUT if an argument has an illegal value - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVodeSetErrHandlerFn(void *cvode_mem, CVErrHandlerFn ehfun, void *eh_data); -SUNDIALS_EXPORT int CVodeSetErrFile(void *cvode_mem, FILE *errfp); -SUNDIALS_EXPORT int CVodeSetUserData(void *cvode_mem, void *user_data); -SUNDIALS_EXPORT int CVodeSetMaxOrd(void *cvode_mem, int maxord); -SUNDIALS_EXPORT int CVodeSetMaxNumSteps(void *cvode_mem, long int mxsteps); -SUNDIALS_EXPORT int CVodeSetMaxHnilWarns(void *cvode_mem, int mxhnil); -SUNDIALS_EXPORT int CVodeSetStabLimDet(void *cvode_mem, booleantype stldet); -SUNDIALS_EXPORT int CVodeSetInitStep(void *cvode_mem, realtype hin); -SUNDIALS_EXPORT int CVodeSetMinStep(void *cvode_mem, realtype hmin); -SUNDIALS_EXPORT int CVodeSetMaxStep(void *cvode_mem, realtype hmax); -SUNDIALS_EXPORT int CVodeSetStopTime(void *cvode_mem, realtype tstop); -SUNDIALS_EXPORT int CVodeSetMaxErrTestFails(void *cvode_mem, int maxnef); -SUNDIALS_EXPORT int CVodeSetMaxNonlinIters(void *cvode_mem, int maxcor); -SUNDIALS_EXPORT int CVodeSetMaxConvFails(void *cvode_mem, int maxncf); -SUNDIALS_EXPORT int CVodeSetNonlinConvCoef(void *cvode_mem, realtype nlscoef); - -SUNDIALS_EXPORT int CVodeSetIterType(void *cvode_mem, int iter); - -SUNDIALS_EXPORT int CVodeSetRootDirection(void *cvode_mem, int *rootdir); -SUNDIALS_EXPORT int CVodeSetNoInactiveRootWarn(void *cvode_mem); - -/* - * ----------------------------------------------------------------- - * Function : CVodeInit - * ----------------------------------------------------------------- - * CVodeInit allocates and initializes memory for a problem to - * to be solved by CVODE. - * - * cvode_mem is pointer to CVODE memory returned by CVodeCreate. - * - * f is the name of the C function defining the right-hand - * side function in y' = f(t,y). - * - * t0 is the initial value of t. - * - * y0 is the initial condition vector y(t0). - * - * Return flag: - * CV_SUCCESS if successful - * CV_MEM_NULL if the cvode memory was NULL - * CV_MEM_FAIL if a memory allocation failed - * CV_ILL_INPUT f an argument has an illegal value. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVodeInit(void *cvode_mem, CVRhsFn f, realtype t0, N_Vector y0); - -/* - * ----------------------------------------------------------------- - * Function : CVodeReInit - * ----------------------------------------------------------------- - * CVodeReInit re-initializes CVode for the solution of a problem, - * where a prior call to CVodeInit has been made with the same - * problem size N. CVodeReInit performs the same input checking - * and initializations that CVodeInit does. - * But it does no memory allocation, assuming that the existing - * internal memory is sufficient for the new problem. - * - * The use of CVodeReInit requires that the maximum method order, - * maxord, is no larger for the new problem than for the problem - * specified in the last call to CVodeInit. This condition is - * automatically fulfilled if the multistep method parameter lmm - * is unchanged (or changed from CV_ADAMS to CV_BDF) and the default - * value for maxord is specified. - * - * All of the arguments to CVodeReInit have names and meanings - * identical to those of CVodeInit. - * - * The return value of CVodeReInit is equal to CV_SUCCESS = 0 if - * there were no errors; otherwise it is a negative int equal to: - * CV_MEM_NULL indicating cvode_mem was NULL (i.e., - * CVodeCreate has not been called). - * CV_NO_MALLOC indicating that cvode_mem has not been - * allocated (i.e., CVodeInit has not been - * called). - * CV_ILL_INPUT indicating an input argument was illegal - * (including an attempt to increase maxord). - * In case of an error return, an error message is also printed. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVodeReInit(void *cvode_mem, realtype t0, N_Vector y0); - -/* - * ----------------------------------------------------------------- - * Functions : CVodeSStolerances - * CVodeSVtolerances - * CVodeWFtolerances - * ----------------------------------------------------------------- - * - * These functions specify the integration tolerances. One of them - * MUST be called before the first call to CVode. - * - * CVodeSStolerances specifies scalar relative and absolute tolerances. - * CVodeSVtolerances specifies scalar relative tolerance and a vector - * absolute tolerance (a potentially different absolute tolerance - * for each vector component). - * CVodeWFtolerances specifies a user-provides function (of type CVEwtFn) - * which will be called to set the error weight vector. - * - * The tolerances reltol and abstol define a vector of error weights, - * ewt, with components - * ewt[i] = 1/(reltol*abs(y[i]) + abstol) (in the SS case), or - * ewt[i] = 1/(reltol*abs(y[i]) + abstol[i]) (in the SV case). - * This vector is used in all error and convergence tests, which - * use a weighted RMS norm on all error-like vectors v: - * WRMSnorm(v) = sqrt( (1/N) sum(i=1..N) (v[i]*ewt[i])^2 ), - * where N is the problem dimension. - * - * The return value of these functions is equal to CV_SUCCESS = 0 if - * there were no errors; otherwise it is a negative int equal to: - * CV_MEM_NULL indicating cvode_mem was NULL (i.e., - * CVodeCreate has not been called). - * CV_NO_MALLOC indicating that cvode_mem has not been - * allocated (i.e., CVodeInit has not been - * called). - * CV_ILL_INPUT indicating an input argument was illegal - * (e.g. a negative tolerance) - * In case of an error return, an error message is also printed. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVodeSStolerances(void *cvode_mem, realtype reltol, realtype abstol); -SUNDIALS_EXPORT int CVodeSVtolerances(void *cvode_mem, realtype reltol, N_Vector abstol); -SUNDIALS_EXPORT int CVodeWFtolerances(void *cvode_mem, CVEwtFn efun); - -/* - * ----------------------------------------------------------------- - * Function : CVodeRootInit - * ----------------------------------------------------------------- - * CVodeRootInit initializes a rootfinding problem to be solved - * during the integration of the ODE system. It must be called - * after CVodeCreate, and before CVode. The arguments are: - * - * cvode_mem = pointer to CVODE memory returned by CVodeCreate. - * - * nrtfn = number of functions g_i, an int >= 0. - * - * g = name of user-supplied function, of type CVRootFn, - * defining the functions g_i whose roots are sought. - * - * If a new problem is to be solved with a call to CVodeReInit, - * where the new problem has no root functions but the prior one - * did, then call CVodeRootInit with nrtfn = 0. - * - * The return value of CVodeRootInit is CV_SUCCESS = 0 if there were - * no errors; otherwise it is a negative int equal to: - * CV_MEM_NULL indicating cvode_mem was NULL, or - * CV_MEM_FAIL indicating a memory allocation failed. - * (including an attempt to increase maxord). - * CV_ILL_INPUT indicating nrtfn > 0 but g = NULL. - * In case of an error return, an error message is also printed. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVodeRootInit(void *cvode_mem, int nrtfn, CVRootFn g); - -/* - * ----------------------------------------------------------------- - * Function : CVode - * ----------------------------------------------------------------- - * CVode integrates the ODE over an interval in t. - * If itask is CV_NORMAL, then the solver integrates from its - * current internal t value to a point at or beyond tout, then - * interpolates to t = tout and returns y(tout) in the user- - * allocated vector yout. If itask is CV_ONE_STEP, then the solver - * takes one internal time step and returns in yout the value of - * y at the new internal time. In this case, tout is used only - * during the first call to CVode to determine the direction of - * integration and the rough scale of the t variable. If tstop is - * enabled (through a call to CVodeSetStopTime), then CVode returns - * the solution at tstop. Once the integrator returns at a tstop - * time, any future testing for tstop is disabled (and can be - * reenabled only though a new call to CVodeSetStopTime). - * The time reached by the solver is placed in (*tret). The - * user is responsible for allocating the memory for this value. - * - * cvode_mem is the pointer to CVODE memory returned by - * CVodeCreate. - * - * tout is the next time at which a computed solution is desired. - * - * yout is the computed solution vector. In CV_NORMAL mode with no - * errors and no roots found, yout=y(tout). - * - * tret is a pointer to a real location. CVode sets (*tret) to - * the time reached by the solver and returns - * yout=y(*tret). - * - * itask is CV_NORMAL or CV_ONE_STEP. These two modes are described above. - * - * Here is a brief description of each return value: - * - * CV_SUCCESS: CVode succeeded and no roots were found. - * - * CV_ROOT_RETURN: CVode succeeded, and found one or more roots. - * If nrtfn > 1, call CVodeGetRootInfo to see - * which g_i were found to have a root at (*tret). - * - * CV_TSTOP_RETURN: CVode succeeded and returned at tstop. - * - * CV_MEM_NULL: The cvode_mem argument was NULL. - * - * CV_NO_MALLOC: cvode_mem was not allocated. - * - * CV_ILL_INPUT: One of the inputs to CVode is illegal. This - * includes the situation when a component of the - * error weight vectors becomes < 0 during - * internal time-stepping. It also includes the - * situation where a root of one of the root - * functions was found both at t0 and very near t0. - * The ILL_INPUT flag will also be returned if the - * linear solver routine CV--- (called by the user - * after calling CVodeCreate) failed to set one of - * the linear solver-related fields in cvode_mem or - * if the linear solver's init routine failed. In - * any case, the user should see the printed - * error message for more details. - * - * CV_TOO_MUCH_WORK: The solver took mxstep internal steps but - * could not reach tout. The default value for - * mxstep is MXSTEP_DEFAULT = 500. - * - * CV_TOO_MUCH_ACC: The solver could not satisfy the accuracy - * demanded by the user for some internal step. - * - * CV_ERR_FAILURE: Error test failures occurred too many times - * (= MXNEF = 7) during one internal time step or - * occurred with |h| = hmin. - * - * CV_CONV_FAILURE: Convergence test failures occurred too many - * times (= MXNCF = 10) during one internal time - * step or occurred with |h| = hmin. - * - * CV_LINIT_FAIL: The linear solver's initialization function - * failed. - * - * CV_LSETUP_FAIL: The linear solver's setup routine failed in an - * unrecoverable manner. - * - * CV_LSOLVE_FAIL: The linear solver's solve routine failed in an - * unrecoverable manner. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVode(void *cvode_mem, realtype tout, N_Vector yout, - realtype *tret, int itask); - -/* - * ----------------------------------------------------------------- - * Function : CVodeGetDky - * ----------------------------------------------------------------- - * CVodeGetDky computes the kth derivative of the y function at - * time t, where tn-hu <= t <= tn, tn denotes the current - * internal time reached, and hu is the last internal step size - * successfully used by the solver. The user may request - * k=0, 1, ..., qu, where qu is the order last used. The - * derivative vector is returned in dky. This vector must be - * allocated by the caller. It is only legal to call this - * function after a successful return from CVode. - * - * cvode_mem is the pointer to CVODE memory returned by - * CVodeCreate. - * - * t is the time at which the kth derivative of y is evaluated. - * The legal range for t is [tn-hu,tn] as described above. - * - * k is the order of the derivative of y to be computed. The - * legal range for k is [0,qu] as described above. - * - * dky is the output derivative vector [((d/dy)^k)y](t). - * - * The return value for CVodeGetDky is one of: - * - * CV_SUCCESS: CVodeGetDky succeeded. - * - * CV_BAD_K: k is not in the range 0, 1, ..., qu. - * - * CV_BAD_T: t is not in the interval [tn-hu,tn]. - * - * CV_BAD_DKY: The dky argument was NULL. - * - * CV_MEM_NULL: The cvode_mem argument was NULL. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVodeGetDky(void *cvode_mem, realtype t, int k, N_Vector dky); - -/* - * ----------------------------------------------------------------- - * Integrator optional output extraction functions - * ----------------------------------------------------------------- - * The following functions can be called to get optional outputs - * and statistics related to the main integrator. - * ----------------------------------------------------------------- - * CVodeGetWorkSpace returns the CVODE real and integer workspaces - * CVodeGetNumSteps returns the cumulative number of internal - * steps taken by the solver - * CVodeGetNumRhsEvals returns the number of calls to the user's - * f function - * CVodeGetNumLinSolvSetups returns the number of calls made to - * the linear solver's setup routine - * CVodeGetNumErrTestFails returns the number of local error test - * failures that have occured - * CVodeGetLastOrder returns the order used during the last - * internal step - * CVodeGetCurrentOrder returns the order to be used on the next - * internal step - * CVodeGetNumStabLimOrderReds returns the number of order - * reductions due to stability limit - * detection - * CVodeGetActualInitStep returns the actual initial step size - * used by CVODE - * CVodeGetLastStep returns the step size for the last internal - * step - * CVodeGetCurrentStep returns the step size to be attempted on - * the next internal step - * CVodeGetCurrentTime returns the current internal time reached - * by the solver - * CVodeGetTolScaleFactor returns a suggested factor by which the - * user's tolerances should be scaled when - * too much accuracy has been requested for - * some internal step - * CVodeGetErrWeights returns the current error weight vector. - * The user must allocate space for eweight. - * CVodeGetEstLocalErrors returns the vector of estimated local - * errors. The user must allocate space - * for ele. - * CVodeGetNumGEvals returns the number of calls to the user's - * g function (for rootfinding) - * CVodeGetRootInfo returns the indices for which g_i was found to - * have a root. The user must allocate space for - * rootsfound. For i = 0 ... nrtfn-1, - * rootsfound[i] = 1 if g_i has a root, and = 0 if not. - * - * CVodeGet* return values: - * CV_SUCCESS if succesful - * CV_MEM_NULL if the cvode memory was NULL - * CV_NO_SLDET if stability limit was not turned on - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVodeGetWorkSpace(void *cvode_mem, long int *lenrw, long int *leniw); -SUNDIALS_EXPORT int CVodeGetNumSteps(void *cvode_mem, long int *nsteps); -SUNDIALS_EXPORT int CVodeGetNumRhsEvals(void *cvode_mem, long int *nfevals); -SUNDIALS_EXPORT int CVodeGetNumLinSolvSetups(void *cvode_mem, long int *nlinsetups); -SUNDIALS_EXPORT int CVodeGetNumErrTestFails(void *cvode_mem, long int *netfails); -SUNDIALS_EXPORT int CVodeGetLastOrder(void *cvode_mem, int *qlast); -SUNDIALS_EXPORT int CVodeGetCurrentOrder(void *cvode_mem, int *qcur); -SUNDIALS_EXPORT int CVodeGetNumStabLimOrderReds(void *cvode_mem, long int *nslred); -SUNDIALS_EXPORT int CVodeGetActualInitStep(void *cvode_mem, realtype *hinused); -SUNDIALS_EXPORT int CVodeGetLastStep(void *cvode_mem, realtype *hlast); -SUNDIALS_EXPORT int CVodeGetCurrentStep(void *cvode_mem, realtype *hcur); -SUNDIALS_EXPORT int CVodeGetCurrentTime(void *cvode_mem, realtype *tcur); -SUNDIALS_EXPORT int CVodeGetTolScaleFactor(void *cvode_mem, realtype *tolsfac); -SUNDIALS_EXPORT int CVodeGetErrWeights(void *cvode_mem, N_Vector eweight); -SUNDIALS_EXPORT int CVodeGetEstLocalErrors(void *cvode_mem, N_Vector ele); -SUNDIALS_EXPORT int CVodeGetNumGEvals(void *cvode_mem, long int *ngevals); -SUNDIALS_EXPORT int CVodeGetRootInfo(void *cvode_mem, int *rootsfound); - -/* - * ----------------------------------------------------------------- - * As a convenience, the following functions provides the - * optional outputs in one group. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVodeGetIntegratorStats(void *cvode_mem, long int *nsteps, - long int *nfevals, long int *nlinsetups, - long int *netfails, int *qlast, - int *qcur, realtype *hinused, realtype *hlast, - realtype *hcur, realtype *tcur); - -/* - * ----------------------------------------------------------------- - * Nonlinear solver optional output extraction functions - * ----------------------------------------------------------------- - * The following functions can be called to get optional outputs - * and statistics related to the nonlinear solver. - * ----------------------------------------------------------------- - * CVodeGetNumNonlinSolvIters returns the number of nonlinear - * solver iterations performed. - * CVodeGetNumNonlinSolvConvFails returns the number of nonlinear - * convergence failures. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVodeGetNumNonlinSolvIters(void *cvode_mem, long int *nniters); -SUNDIALS_EXPORT int CVodeGetNumNonlinSolvConvFails(void *cvode_mem, long int *nncfails); - -/* - * ----------------------------------------------------------------- - * As a convenience, the following function provides the - * nonlinear solver optional outputs in a group. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVodeGetNonlinSolvStats(void *cvode_mem, long int *nniters, - long int *nncfails); - -/* - * ----------------------------------------------------------------- - * The following function returns the name of the constant - * associated with a CVODE return flag - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT char *CVodeGetReturnFlagName(int flag); - -/* - * ----------------------------------------------------------------- - * Function : CVodeFree - * ----------------------------------------------------------------- - * CVodeFree frees the problem memory cvode_mem allocated by - * CVodeCreate and CVodeInit. Its only argument is the pointer - * cvode_mem returned by CVodeCreate. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void CVodeFree(void **cvode_mem); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/amuse/community/secularmultiple/src/cvode/cvode_dense.c b/src/amuse/community/secularmultiple/src/cvode/cvode_dense.c deleted file mode 100755 index 5039982704..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/cvode_dense.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.10 $ - * $Date: 2009/02/17 02:42:29 $ - * ----------------------------------------------------------------- - * Programmer(s): Scott D. Cohen, Alan C. Hindmarsh and - * Radu Serban @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the impleentation file for the CVDENSE linear solver. - * ----------------------------------------------------------------- - */ - -#include -#include - -#include "cvode_dense.h" -#include "cvode_direct_impl.h" -#include "cvode_impl.h" - -#include "sundials_math.h" - -/* Constants */ - -#define ZERO RCONST(0.0) -#define ONE RCONST(1.0) -#define TWO RCONST(2.0) - -/* CVDENSE linit, lsetup, lsolve, and lfree routines */ - -static int cvDenseInit(CVodeMem cv_mem); - -static int cvDenseSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, - N_Vector fpred, booleantype *jcurPtr, - N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3); - -static int cvDenseSolve(CVodeMem cv_mem, N_Vector b, N_Vector weight, - N_Vector ycur, N_Vector fcur); - -static void cvDenseFree(CVodeMem cv_mem); - -/* Readability Replacements */ - -#define lmm (cv_mem->cv_lmm) -#define f (cv_mem->cv_f) -#define nst (cv_mem->cv_nst) -#define tn (cv_mem->cv_tn) -#define h (cv_mem->cv_h) -#define gamma (cv_mem->cv_gamma) -#define gammap (cv_mem->cv_gammap) -#define gamrat (cv_mem->cv_gamrat) -#define ewt (cv_mem->cv_ewt) -#define linit (cv_mem->cv_linit) -#define lsetup (cv_mem->cv_lsetup) -#define lsolve (cv_mem->cv_lsolve) -#define lfree (cv_mem->cv_lfree) -#define lmem (cv_mem->cv_lmem) -#define vec_tmpl (cv_mem->cv_tempv) -#define setupNonNull (cv_mem->cv_setupNonNull) - -#define mtype (cvdls_mem->d_type) -#define n (cvdls_mem->d_n) -#define jacDQ (cvdls_mem->d_jacDQ) -#define jac (cvdls_mem->d_djac) -#define M (cvdls_mem->d_M) -#define pivots (cvdls_mem->d_pivots) -#define savedJ (cvdls_mem->d_savedJ) -#define nstlj (cvdls_mem->d_nstlj) -#define nje (cvdls_mem->d_nje) -#define nfeDQ (cvdls_mem->d_nfeDQ) -#define J_data (cvdls_mem->d_J_data) -#define last_flag (cvdls_mem->d_last_flag) - -/* - * ----------------------------------------------------------------- - * CVDense - * ----------------------------------------------------------------- - * This routine initializes the memory record and sets various function - * fields specific to the dense linear solver module. CVDense first - * calls the existing lfree routine if this is not NULL. Then it sets - * the cv_linit, cv_lsetup, cv_lsolve, cv_lfree fields in (*cvode_mem) - * to be cvDenseInit, cvDenseSetup, cvDenseSolve, and cvDenseFree, - * respectively. It allocates memory for a structure of type - * CVDlsMemRec and sets the cv_lmem field in (*cvode_mem) to the - * address of this structure. It sets setupNonNull in (*cvode_mem) to - * TRUE, and the d_jac field to the default cvDlsDenseDQJac. - * Finally, it allocates memory for M, savedJ, and pivots. - * The return value is SUCCESS = 0, or LMEM_FAIL = -1. - * - * NOTE: The dense linear solver assumes a serial implementation - * of the NVECTOR package. Therefore, CVDense will first - * test for compatible a compatible N_Vector internal - * representation by checking that N_VGetArrayPointer and - * N_VSetArrayPointer exist. - * ----------------------------------------------------------------- - */ - -int CVDense(void *cvode_mem, int N) -{ - CVodeMem cv_mem; - CVDlsMem cvdls_mem; - - /* Return immediately if cvode_mem is NULL */ - if (cvode_mem == NULL) { - CVProcessError(NULL, CVDLS_MEM_NULL, "CVDENSE", "CVDense", MSGD_CVMEM_NULL); - return(CVDLS_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - /* Test if the NVECTOR package is compatible with the DENSE solver */ - if (vec_tmpl->ops->nvgetarraypointer == NULL || - vec_tmpl->ops->nvsetarraypointer == NULL) { - CVProcessError(cv_mem, CVDLS_ILL_INPUT, "CVDENSE", "CVDense", MSGD_BAD_NVECTOR); - return(CVDLS_ILL_INPUT); - } - - if (lfree !=NULL) lfree(cv_mem); - - /* Set four main function fields in cv_mem */ - linit = cvDenseInit; - lsetup = cvDenseSetup; - lsolve = cvDenseSolve; - lfree = cvDenseFree; - - /* Get memory for CVDlsMemRec */ - cvdls_mem = NULL; - cvdls_mem = (CVDlsMem) malloc(sizeof(struct CVDlsMemRec)); - if (cvdls_mem == NULL) { - CVProcessError(cv_mem, CVDLS_MEM_FAIL, "CVDENSE", "CVDense", MSGD_MEM_FAIL); - return(CVDLS_MEM_FAIL); - } - - /* Set matrix type */ - mtype = SUNDIALS_DENSE; - - /* Initialize Jacobian-related data */ - jacDQ = TRUE; - jac = NULL; - J_data = NULL; - - last_flag = CVDLS_SUCCESS; - - setupNonNull = TRUE; - - /* Set problem dimension */ - n = N; - - /* Allocate memory for M, savedJ, and pivot array */ - - M = NULL; - M = NewDenseMat(N, N); - if (M == NULL) { - CVProcessError(cv_mem, CVDLS_MEM_FAIL, "CVDENSE", "CVDense", MSGD_MEM_FAIL); - free(cvdls_mem); cvdls_mem = NULL; - return(CVDLS_MEM_FAIL); - } - savedJ = NULL; - savedJ = NewDenseMat(N, N); - if (savedJ == NULL) { - CVProcessError(cv_mem, CVDLS_MEM_FAIL, "CVDENSE", "CVDense", MSGD_MEM_FAIL); - DestroyMat(M); - free(cvdls_mem); cvdls_mem = NULL; - return(CVDLS_MEM_FAIL); - } - pivots = NULL; - pivots = NewIntArray(N); - if (pivots == NULL) { - CVProcessError(cv_mem, CVDLS_MEM_FAIL, "CVDENSE", "CVDense", MSGD_MEM_FAIL); - DestroyMat(M); - DestroyMat(savedJ); - free(cvdls_mem); cvdls_mem = NULL; - return(CVDLS_MEM_FAIL); - } - - /* Attach linear solver memory to integrator memory */ - lmem = cvdls_mem; - - return(CVDLS_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * cvDenseInit - * ----------------------------------------------------------------- - * This routine does remaining initializations specific to the dense - * linear solver. - * ----------------------------------------------------------------- - */ - -static int cvDenseInit(CVodeMem cv_mem) -{ - CVDlsMem cvdls_mem; - - cvdls_mem = (CVDlsMem) lmem; - - nje = 0; - nfeDQ = 0; - nstlj = 0; - - /* Set Jacobian function and data, depending on jacDQ */ - if (jacDQ) { - jac = cvDlsDenseDQJac; - J_data = cv_mem; - } else { - J_data = cv_mem->cv_user_data; - } - - last_flag = CVDLS_SUCCESS; - return(0); -} - -/* - * ----------------------------------------------------------------- - * cvDenseSetup - * ----------------------------------------------------------------- - * This routine does the setup operations for the dense linear solver. - * It makes a decision whether or not to call the Jacobian evaluation - * routine based on various state variables, and if not it uses the - * saved copy. In any case, it constructs the Newton matrix - * M = I - gamma*J, updates counters, and calls the dense LU - * factorization routine. - * ----------------------------------------------------------------- - */ - -static int cvDenseSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, - N_Vector fpred, booleantype *jcurPtr, - N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3) -{ - booleantype jbad, jok; - realtype dgamma; - long int ier; - CVDlsMem cvdls_mem; - int retval; - - cvdls_mem = (CVDlsMem) lmem; - - /* Use nst, gamma/gammap, and convfail to set J eval. flag jok */ - - dgamma = ABS((gamma/gammap) - ONE); - jbad = (nst == 0) || (nst > nstlj + CVD_MSBJ) || - ((convfail == CV_FAIL_BAD_J) && (dgamma < CVD_DGMAX)) || - (convfail == CV_FAIL_OTHER); - jok = !jbad; - - if (jok) { - - /* If jok = TRUE, use saved copy of J */ - *jcurPtr = FALSE; - DenseCopy(savedJ, M); - - } else { - - /* If jok = FALSE, call jac routine for new J value */ - nje++; - nstlj = nst; - *jcurPtr = TRUE; - SetToZero(M); - - retval = jac(n, tn, ypred, fpred, M, J_data, vtemp1, vtemp2, vtemp3); - if (retval < 0) { - CVProcessError(cv_mem, CVDLS_JACFUNC_UNRECVR, "CVDENSE", "cvDenseSetup", MSGD_JACFUNC_FAILED); - last_flag = CVDLS_JACFUNC_UNRECVR; - return(-1); - } - if (retval > 0) { - last_flag = CVDLS_JACFUNC_RECVR; - return(1); - } - - DenseCopy(M, savedJ); - - } - - /* Scale and add I to get M = I - gamma*J */ - DenseScale(-gamma, M); - AddIdentity(M); - - /* Do LU factorization of M */ - ier = DenseGETRF(M, pivots); - - /* Return 0 if the LU was complete; otherwise return 1 */ - last_flag = ier; - if (ier > 0) return(1); - return(0); -} - -/* - * ----------------------------------------------------------------- - * cvDenseSolve - * ----------------------------------------------------------------- - * This routine handles the solve operation for the dense linear solver - * by calling the dense backsolve routine. The returned value is 0. - * ----------------------------------------------------------------- - */ - -static int cvDenseSolve(CVodeMem cv_mem, N_Vector b, N_Vector weight, - N_Vector ycur, N_Vector fcur) -{ - CVDlsMem cvdls_mem; - realtype *bd; - - cvdls_mem = (CVDlsMem) lmem; - - bd = N_VGetArrayPointer(b); - - DenseGETRS(M, pivots, bd); - - /* If CV_BDF, scale the correction to account for change in gamma */ - if ((lmm == CV_BDF) && (gamrat != ONE)) { - N_VScale(TWO/(ONE + gamrat), b, b); - } - - last_flag = CVDLS_SUCCESS; - return(0); -} - -/* - * ----------------------------------------------------------------- - * cvDenseFree - * ----------------------------------------------------------------- - * This routine frees memory specific to the dense linear solver. - * ----------------------------------------------------------------- - */ - -static void cvDenseFree(CVodeMem cv_mem) -{ - CVDlsMem cvdls_mem; - - cvdls_mem = (CVDlsMem) lmem; - - DestroyMat(M); - DestroyMat(savedJ); - DestroyArray(pivots); - free(cvdls_mem); cvdls_mem = NULL; -} - diff --git a/src/amuse/community/secularmultiple/src/cvode/cvode_dense.h b/src/amuse/community/secularmultiple/src/cvode/cvode_dense.h deleted file mode 100755 index 70bfc0a6ab..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/cvode_dense.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.5 $ - * $Date: 2008/04/18 19:42:36 $ - * ----------------------------------------------------------------- - * Programmer(s): Scott D. Cohen, Alan C. Hindmarsh and - * Radu Serban @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the header file for the CVODE dense linear solver, CVDENSE. - * ----------------------------------------------------------------- - */ - -#ifndef _CVDENSE_H -#define _CVDENSE_H - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -#include "cvode_direct.h" -#include "sundials_dense.h" - -/* - * ----------------------------------------------------------------- - * Function: CVDense - * ----------------------------------------------------------------- - * A call to the CVDense function links the main integrator with - * the CVDENSE linear solver. - * - * cvode_mem is the pointer to the integrator memory returned by - * CVodeCreate. - * - * N is the size of the ODE system. - * - * The return value of CVDense is one of: - * CVDLS_SUCCESS if successful - * CVDLS_MEM_NULL if the cvode memory was NULL - * CVDLS_MEM_FAIL if there was a memory allocation failure - * CVDLS_ILL_INPUT if a required vector operation is missing - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVDense(void *cvode_mem, int N); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/amuse/community/secularmultiple/src/cvode/cvode_direct.c b/src/amuse/community/secularmultiple/src/cvode/cvode_direct.c deleted file mode 100755 index 99dfdd53de..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/cvode_direct.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.4 $ - * $Date: 2008/04/18 19:42:39 $ - * ----------------------------------------------------------------- - * Programmer: Radu Serban @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2006, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the implementation file for the CVDLS linear solvers - * ----------------------------------------------------------------- - */ - -/* - * ================================================================= - * IMPORTED HEADER FILES - * ================================================================= - */ - -#include -#include - -#include "cvode_impl.h" -#include "cvode_direct_impl.h" -#include "sundials_math.h" - -/* - * ================================================================= - * FUNCTION SPECIFIC CONSTANTS - * ================================================================= - */ - -/* Constant for DQ Jacobian approximation */ -#define MIN_INC_MULT RCONST(1000.0) - -#define ZERO RCONST(0.0) -#define ONE RCONST(1.0) -#define TWO RCONST(2.0) - -/* - * ================================================================= - * READIBILITY REPLACEMENTS - * ================================================================= - */ - -#define f (cv_mem->cv_f) -#define user_data (cv_mem->cv_user_data) -#define uround (cv_mem->cv_uround) -#define nst (cv_mem->cv_nst) -#define tn (cv_mem->cv_tn) -#define h (cv_mem->cv_h) -#define gamma (cv_mem->cv_gamma) -#define gammap (cv_mem->cv_gammap) -#define gamrat (cv_mem->cv_gamrat) -#define ewt (cv_mem->cv_ewt) - -#define lmem (cv_mem->cv_lmem) - -#define mtype (cvdls_mem->d_type) -#define n (cvdls_mem->d_n) -#define ml (cvdls_mem->d_ml) -#define mu (cvdls_mem->d_mu) -#define smu (cvdls_mem->d_smu) -#define jacDQ (cvdls_mem->d_jacDQ) -#define djac (cvdls_mem->d_djac) -#define bjac (cvdls_mem->d_bjac) -#define M (cvdls_mem->d_M) -#define nje (cvdls_mem->d_nje) -#define nfeDQ (cvdls_mem->d_nfeDQ) -#define last_flag (cvdls_mem->d_last_flag) - -/* - * ================================================================= - * EXPORTED FUNCTIONS - * ================================================================= - */ - -/* - * CVDlsSetDenseJacFn specifies the dense Jacobian function. - */ -int CVDlsSetDenseJacFn(void *cvode_mem, CVDlsDenseJacFn jac) -{ - CVodeMem cv_mem; - CVDlsMem cvdls_mem; - - /* Return immediately if cvode_mem is NULL */ - if (cvode_mem == NULL) { - CVProcessError(NULL, CVDLS_MEM_NULL, "CVDLS", "CVDlsSetDenseJacFn", MSGD_CVMEM_NULL); - return(CVDLS_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - if (lmem == NULL) { - CVProcessError(cv_mem, CVDLS_LMEM_NULL, "CVDLS", "CVDlsSetDenseJacFn", MSGD_LMEM_NULL); - return(CVDLS_LMEM_NULL); - } - cvdls_mem = (CVDlsMem) lmem; - - if (jac != NULL) { - jacDQ = FALSE; - djac = jac; - } else { - jacDQ = TRUE; - } - - return(CVDLS_SUCCESS); -} - -/* - * CVDlsSetBandJacFn specifies the band Jacobian function. - */ -int CVDlsSetBandJacFn(void *cvode_mem, CVDlsBandJacFn jac) -{ - CVodeMem cv_mem; - CVDlsMem cvdls_mem; - - /* Return immediately if cvode_mem is NULL */ - if (cvode_mem == NULL) { - CVProcessError(NULL, CVDLS_MEM_NULL, "CVDLS", "CVDlsSetBandJacFn", MSGD_CVMEM_NULL); - return(CVDLS_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - if (lmem == NULL) { - CVProcessError(cv_mem, CVDLS_LMEM_NULL, "CVDLS", "CVDlsSetBandJacFn", MSGD_LMEM_NULL); - return(CVDLS_LMEM_NULL); - } - cvdls_mem = (CVDlsMem) lmem; - - if (jac != NULL) { - jacDQ = FALSE; - bjac = jac; - } else { - jacDQ = TRUE; - } - - return(CVDLS_SUCCESS); -} - -/* - * CVDlsGetWorkSpace returns the length of workspace allocated for the - * CVDLS linear solver. - */ -int CVDlsGetWorkSpace(void *cvode_mem, long int *lenrwLS, long int *leniwLS) -{ - CVodeMem cv_mem; - CVDlsMem cvdls_mem; - - /* Return immediately if cvode_mem is NULL */ - if (cvode_mem == NULL) { - CVProcessError(NULL, CVDLS_MEM_NULL, "CVDLS", "CVDlsGetWorkSpace", MSGD_CVMEM_NULL); - return(CVDLS_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - if (lmem == NULL) { - CVProcessError(cv_mem, CVDLS_LMEM_NULL, "CVDLS", "CVDlsGetWorkSpace", MSGD_LMEM_NULL); - return(CVDLS_LMEM_NULL); - } - cvdls_mem = (CVDlsMem) lmem; - - if (mtype == SUNDIALS_DENSE) { - *lenrwLS = 2*n*n; - *leniwLS = n; - } else if (mtype == SUNDIALS_BAND) { - *lenrwLS = n*(smu + mu + 2*ml + 2); - *leniwLS = n; - } - - return(CVDLS_SUCCESS); -} - -/* - * CVDlsGetNumJacEvals returns the number of Jacobian evaluations. - */ -int CVDlsGetNumJacEvals(void *cvode_mem, long int *njevals) -{ - CVodeMem cv_mem; - CVDlsMem cvdls_mem; - - /* Return immediately if cvode_mem is NULL */ - if (cvode_mem == NULL) { - CVProcessError(NULL, CVDLS_MEM_NULL, "CVDLS", "CVDlsGetNumJacEvals", MSGD_CVMEM_NULL); - return(CVDLS_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - if (lmem == NULL) { - CVProcessError(cv_mem, CVDLS_LMEM_NULL, "CVDLS", "CVDlsGetNumJacEvals", MSGD_LMEM_NULL); - return(CVDLS_LMEM_NULL); - } - cvdls_mem = (CVDlsMem) lmem; - - *njevals = nje; - - return(CVDLS_SUCCESS); -} - -/* - * CVDlsGetNumRhsEvals returns the number of calls to the ODE function - * needed for the DQ Jacobian approximation. - */ -int CVDlsGetNumRhsEvals(void *cvode_mem, long int *nfevalsLS) -{ - CVodeMem cv_mem; - CVDlsMem cvdls_mem; - - /* Return immediately if cvode_mem is NULL */ - if (cvode_mem == NULL) { - CVProcessError(NULL, CVDLS_MEM_NULL, "CVDLS", "CVDlsGetNumRhsEvals", MSGD_CVMEM_NULL); - return(CVDLS_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - if (lmem == NULL) { - CVProcessError(cv_mem, CVDLS_LMEM_NULL, "CVDLS", "CVDlsGetNumRhsEvals", MSGD_LMEM_NULL); - return(CVDLS_LMEM_NULL); - } - cvdls_mem = (CVDlsMem) lmem; - - *nfevalsLS = nfeDQ; - - return(CVDLS_SUCCESS); -} - -/* - * CVDlsGetReturnFlagName returns the name associated with a CVDLS - * return value. - */ -char *CVDlsGetReturnFlagName(int flag) -{ - char *name; - - name = (char *)malloc(30*sizeof(char)); - - switch(flag) { - case CVDLS_SUCCESS: - sprintf(name,"CVDLS_SUCCESS"); - break; - case CVDLS_MEM_NULL: - sprintf(name,"CVDLS_MEM_NULL"); - break; - case CVDLS_LMEM_NULL: - sprintf(name,"CVDLS_LMEM_NULL"); - break; - case CVDLS_ILL_INPUT: - sprintf(name,"CVDLS_ILL_INPUT"); - break; - case CVDLS_MEM_FAIL: - sprintf(name,"CVDLS_MEM_FAIL"); - break; - case CVDLS_JACFUNC_UNRECVR: - sprintf(name,"CVDLS_JACFUNC_UNRECVR"); - break; - case CVDLS_JACFUNC_RECVR: - sprintf(name,"CVDLS_JACFUNC_RECVR"); - break; - default: - sprintf(name,"NONE"); - } - - return(name); -} - -/* - * CVDlsGetLastFlag returns the last flag set in a CVDLS function. - */ -int CVDlsGetLastFlag(void *cvode_mem, int *flag) -{ - CVodeMem cv_mem; - CVDlsMem cvdls_mem; - - /* Return immediately if cvode_mem is NULL */ - if (cvode_mem == NULL) { - CVProcessError(NULL, CVDLS_MEM_NULL, "CVDLS", "CVDlsGetLastFlag", MSGD_CVMEM_NULL); - return(CVDLS_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - if (lmem == NULL) { - CVProcessError(cv_mem, CVDLS_LMEM_NULL, "CVDLS", "CVDlsGetLastFlag", MSGD_LMEM_NULL); - return(CVDLS_LMEM_NULL); - } - cvdls_mem = (CVDlsMem) lmem; - - *flag = last_flag; - - return(CVDLS_SUCCESS); -} - -/* - * ================================================================= - * DQ JACOBIAN APPROXIMATIONS - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * cvDlsDenseDQJac - * ----------------------------------------------------------------- - * This routine generates a dense difference quotient approximation to - * the Jacobian of f(t,y). It assumes that a dense matrix of type - * DlsMat is stored column-wise, and that elements within each column - * are contiguous. The address of the jth column of J is obtained via - * the macro DENSE_COL and this pointer is associated with an N_Vector - * using the N_VGetArrayPointer/N_VSetArrayPointer functions. - * Finally, the actual computation of the jth column of the Jacobian is - * done with a call to N_VLinearSum. - * ----------------------------------------------------------------- - */ - -int cvDlsDenseDQJac(int N, realtype t, - N_Vector y, N_Vector fy, - DlsMat Jac, void *data, - N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) -{ - realtype fnorm, minInc, inc, inc_inv, yjsaved, srur; - realtype *tmp2_data, *y_data, *ewt_data; - N_Vector ftemp, jthCol; - int j; - int retval = 0; - - CVodeMem cv_mem; - CVDlsMem cvdls_mem; - - /* data points to cvode_mem */ - cv_mem = (CVodeMem) data; - cvdls_mem = (CVDlsMem) lmem; - - /* Save pointer to the array in tmp2 */ - tmp2_data = N_VGetArrayPointer(tmp2); - - /* Rename work vectors for readibility */ - ftemp = tmp1; - jthCol = tmp2; - - /* Obtain pointers to the data for ewt, y */ - ewt_data = N_VGetArrayPointer(ewt); - y_data = N_VGetArrayPointer(y); - - /* Set minimum increment based on uround and norm of f */ - srur = RSqrt(uround); - fnorm = N_VWrmsNorm(fy, ewt); - minInc = (fnorm != ZERO) ? - (MIN_INC_MULT * ABS(h) * uround * N * fnorm) : ONE; - - for (j = 0; j < N; j++) { - - /* Generate the jth col of J(tn,y) */ - - N_VSetArrayPointer(DENSE_COL(Jac,j), jthCol); - - yjsaved = y_data[j]; - inc = MAX(srur*ABS(yjsaved), minInc/ewt_data[j]); - y_data[j] += inc; - - retval = f(t, y, ftemp, user_data); - nfeDQ++; - if (retval != 0) break; - - y_data[j] = yjsaved; - - inc_inv = ONE/inc; - N_VLinearSum(inc_inv, ftemp, -inc_inv, fy, jthCol); - - DENSE_COL(Jac,j) = N_VGetArrayPointer(jthCol); - } - - /* Restore original array pointer in tmp2 */ - N_VSetArrayPointer(tmp2_data, tmp2); - - return(retval); -} - -/* - * ----------------------------------------------------------------- - * cvDlsBandDQJac - * ----------------------------------------------------------------- - * This routine generates a banded difference quotient approximation to - * the Jacobian of f(t,y). It assumes that a band matrix of type - * DlsMat is stored column-wise, and that elements within each column - * are contiguous. This makes it possible to get the address of a column - * of J via the macro BAND_COL and to write a simple for loop to set - * each of the elements of a column in succession. - * ----------------------------------------------------------------- - */ - -int cvDlsBandDQJac(int N, int mupper, int mlower, - realtype t, N_Vector y, N_Vector fy, - DlsMat Jac, void *data, - N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) -{ - N_Vector ftemp, ytemp; - realtype fnorm, minInc, inc, inc_inv, srur; - realtype *col_j, *ewt_data, *fy_data, *ftemp_data, *y_data, *ytemp_data; - int group, i, j, width, ngroups, i1, i2; - int retval = 0; - - CVodeMem cv_mem; - CVDlsMem cvdls_mem; - - /* data points to cvode_mem */ - cv_mem = (CVodeMem) data; - cvdls_mem = (CVDlsMem) lmem; - - /* Rename work vectors for use as temporary values of y and f */ - ftemp = tmp1; - ytemp = tmp2; - - /* Obtain pointers to the data for ewt, fy, ftemp, y, ytemp */ - ewt_data = N_VGetArrayPointer(ewt); - fy_data = N_VGetArrayPointer(fy); - ftemp_data = N_VGetArrayPointer(ftemp); - y_data = N_VGetArrayPointer(y); - ytemp_data = N_VGetArrayPointer(ytemp); - - /* Load ytemp with y = predicted y vector */ - N_VScale(ONE, y, ytemp); - - /* Set minimum increment based on uround and norm of f */ - srur = RSqrt(uround); - fnorm = N_VWrmsNorm(fy, ewt); - minInc = (fnorm != ZERO) ? - (MIN_INC_MULT * ABS(h) * uround * N * fnorm) : ONE; - - /* Set bandwidth and number of column groups for band differencing */ - width = mlower + mupper + 1; - ngroups = MIN(width, N); - - /* Loop over column groups. */ - for (group=1; group <= ngroups; group++) { - - /* Increment all y_j in group */ - for(j=group-1; j < N; j+=width) { - inc = MAX(srur*ABS(y_data[j]), minInc/ewt_data[j]); - ytemp_data[j] += inc; - } - - /* Evaluate f with incremented y */ - - retval = f(tn, ytemp, ftemp, user_data); - nfeDQ++; - if (retval != 0) break; - - /* Restore ytemp, then form and load difference quotients */ - for (j=group-1; j < N; j+=width) { - ytemp_data[j] = y_data[j]; - col_j = BAND_COL(Jac,j); - inc = MAX(srur*ABS(y_data[j]), minInc/ewt_data[j]); - inc_inv = ONE/inc; - i1 = MAX(0, j-mupper); - i2 = MIN(j+mlower, N-1); - for (i=i1; i <= i2; i++) - BAND_COL_ELEM(col_j,i,j) = inc_inv * (ftemp_data[i] - fy_data[i]); - } - } - - return(retval); -} - diff --git a/src/amuse/community/secularmultiple/src/cvode/cvode_direct.h b/src/amuse/community/secularmultiple/src/cvode/cvode_direct.h deleted file mode 100755 index e3fa26ff73..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/cvode_direct.h +++ /dev/null @@ -1,285 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.5 $ - * $Date: 2008/04/18 19:42:36 $ - * ----------------------------------------------------------------- - * Programmer: Radu Serban @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2006, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * Common header file for the direct linear solvers in CVODE. - * ----------------------------------------------------------------- - */ - -#ifndef _CVDLS_H -#define _CVDLS_H - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -#include "sundials_direct.h" -#include "sundials_nvector.h" - -/* - * ================================================================= - * C V D I R E C T C O N S T A N T S - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * CVDLS return values - * ----------------------------------------------------------------- - */ - -#define CVDLS_SUCCESS 0 -#define CVDLS_MEM_NULL -1 -#define CVDLS_LMEM_NULL -2 -#define CVDLS_ILL_INPUT -3 -#define CVDLS_MEM_FAIL -4 - -/* Additional last_flag values */ - -#define CVDLS_JACFUNC_UNRECVR -5 -#define CVDLS_JACFUNC_RECVR -6 - -/* - * ================================================================= - * F U N C T I O N T Y P E S - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * Type: CVDlsDenseJacFn - * ----------------------------------------------------------------- - * - * A dense Jacobian approximation function Jac must be of type - * CVDlsDenseJacFn. Its parameters are: - * - * N is the problem size. - * - * Jac is the dense matrix (of type DlsMat) that will be loaded - * by a CVDlsDenseJacFn with an approximation to the Jacobian - * matrix J = (df_i/dy_j) at the point (t,y). - * - * t is the current value of the independent variable. - * - * y is the current value of the dependent variable vector, - * namely the predicted value of y(t). - * - * fy is the vector f(t,y). - * - * user_data is a pointer to user data - the same as the user_data - * parameter passed to CVodeSetFdata. - * - * tmp1, tmp2, and tmp3 are pointers to memory allocated for - * vectors of length N which can be used by a CVDlsDenseJacFn - * as temporary storage or work space. - * - * A CVDlsDenseJacFn should return 0 if successful, a positive - * value if a recoverable error occurred, and a negative value if - * an unrecoverable error occurred. - * - * ----------------------------------------------------------------- - * - * NOTE: The following are two efficient ways to load a dense Jac: - * (1) (with macros - no explicit data structure references) - * for (j=0; j < Neq; j++) { - * col_j = DENSE_COL(Jac,j); - * for (i=0; i < Neq; i++) { - * generate J_ij = the (i,j)th Jacobian element - * col_j[i] = J_ij; - * } - * } - * (2) (without macros - explicit data structure references) - * for (j=0; j < Neq; j++) { - * col_j = (Jac->data)[j]; - * for (i=0; i < Neq; i++) { - * generate J_ij = the (i,j)th Jacobian element - * col_j[i] = J_ij; - * } - * } - * A third way, using the DENSE_ELEM(A,i,j) macro, is much less - * efficient in general. It is only appropriate for use in small - * problems in which efficiency of access is NOT a major concern. - * - * NOTE: If the user's Jacobian routine needs other quantities, - * they are accessible as follows: hcur (the current stepsize) - * and ewt (the error weight vector) are accessible through - * CVodeGetCurrentStep and CVodeGetErrWeights, respectively - * (see cvode.h). The unit roundoff is available as - * UNIT_ROUNDOFF defined in sundials_types.h. - * - * ----------------------------------------------------------------- - */ - - -typedef int (*CVDlsDenseJacFn)(int N, realtype t, - N_Vector y, N_Vector fy, - DlsMat Jac, void *user_data, - N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); - -/* - * ----------------------------------------------------------------- - * Type: CVDlsBandJacFn - * ----------------------------------------------------------------- - * - * A band Jacobian approximation function Jac must have the - * prototype given below. Its parameters are: - * - * N is the length of all vector arguments. - * - * mupper is the upper half-bandwidth of the approximate banded - * Jacobian. This parameter is the same as the mupper parameter - * passed by the user to the linear solver initialization function. - * - * mlower is the lower half-bandwidth of the approximate banded - * Jacobian. This parameter is the same as the mlower parameter - * passed by the user to the linear solver initialization function. - * - * t is the current value of the independent variable. - * - * y is the current value of the dependent variable vector, - * namely the predicted value of y(t). - * - * fy is the vector f(t,y). - * - * Jac is the band matrix (of type DlsMat) that will be loaded - * by a CVDlsBandJacFn with an approximation to the Jacobian matrix - * Jac = (df_i/dy_j) at the point (t,y). - * Three efficient ways to load J are: - * - * (1) (with macros - no explicit data structure references) - * for (j=0; j < n; j++) { - * col_j = BAND_COL(Jac,j); - * for (i=j-mupper; i <= j+mlower; i++) { - * generate J_ij = the (i,j)th Jacobian element - * BAND_COL_ELEM(col_j,i,j) = J_ij; - * } - * } - * - * (2) (with BAND_COL macro, but without BAND_COL_ELEM macro) - * for (j=0; j < n; j++) { - * col_j = BAND_COL(Jac,j); - * for (k=-mupper; k <= mlower; k++) { - * generate J_ij = the (i,j)th Jacobian element, i=j+k - * col_j[k] = J_ij; - * } - * } - * - * (3) (without macros - explicit data structure references) - * offset = Jac->smu; - * for (j=0; j < n; j++) { - * col_j = ((Jac->data)[j])+offset; - * for (k=-mupper; k <= mlower; k++) { - * generate J_ij = the (i,j)th Jacobian element, i=j+k - * col_j[k] = J_ij; - * } - * } - * Caution: Jac->smu is generally NOT the same as mupper. - * - * The BAND_ELEM(A,i,j) macro is appropriate for use in small - * problems in which efficiency of access is NOT a major concern. - * - * user_data is a pointer to user data - the same as the user_data - * parameter passed to CVodeSetFdata. - * - * NOTE: If the user's Jacobian routine needs other quantities, - * they are accessible as follows: hcur (the current stepsize) - * and ewt (the error weight vector) are accessible through - * CVodeGetCurrentStep and CVodeGetErrWeights, respectively - * (see cvode.h). The unit roundoff is available as - * UNIT_ROUNDOFF defined in sundials_types.h - * - * tmp1, tmp2, and tmp3 are pointers to memory allocated for - * vectors of length N which can be used by a CVDlsBandJacFn - * as temporary storage or work space. - * - * A CVDlsBandJacFn should return 0 if successful, a positive value - * if a recoverable error occurred, and a negative value if an - * unrecoverable error occurred. - * ----------------------------------------------------------------- - */ - -typedef int (*CVDlsBandJacFn)(int N, int mupper, int mlower, - realtype t, N_Vector y, N_Vector fy, - DlsMat Jac, void *user_data, - N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); - -/* - * ================================================================= - * E X P O R T E D F U N C T I O N S - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * Optional inputs to the CVDLS linear solver - * ----------------------------------------------------------------- - * - * CVDlsSetDenseJacFn specifies the dense Jacobian approximation - * routine to be used for a direct dense linear solver. - * - * CVDlsSetBandJacFn specifies the band Jacobian approximation - * routine to be used for a direct band linear solver. - * - * By default, a difference quotient approximation, supplied with - * the solver is used. - * - * The return value is one of: - * CVDLS_SUCCESS if successful - * CVDLS_MEM_NULL if the CVODE memory was NULL - * CVDLS_LMEM_NULL if the linear solver memory was NULL - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVDlsSetDenseJacFn(void *cvode_mem, CVDlsDenseJacFn jac); -SUNDIALS_EXPORT int CVDlsSetBandJacFn(void *cvode_mem, CVDlsBandJacFn jac); - -/* - * ----------------------------------------------------------------- - * Optional outputs from the CVDLS linear solver - * ----------------------------------------------------------------- - * - * CVDlsGetWorkSpace returns the real and integer workspace used - * by the direct linear solver. - * CVDlsGetNumJacEvals returns the number of calls made to the - * Jacobian evaluation routine jac. - * CVDlsGetNumRhsEvals returns the number of calls to the user - * f routine due to finite difference Jacobian - * evaluation. - * CVDlsGetLastFlag returns the last error flag set by any of - * the CVDLS interface functions. - * - * The return value of CVDlsGet* is one of: - * CVDLS_SUCCESS if successful - * CVDLS_MEM_NULL if the CVODE memory was NULL - * CVDLS_LMEM_NULL if the linear solver memory was NULL - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int CVDlsGetWorkSpace(void *cvode_mem, long int *lenrwLS, long int *leniwLS); -SUNDIALS_EXPORT int CVDlsGetNumJacEvals(void *cvode_mem, long int *njevals); -SUNDIALS_EXPORT int CVDlsGetNumRhsEvals(void *cvode_mem, long int *nfevalsLS); -SUNDIALS_EXPORT int CVDlsGetLastFlag(void *cvode_mem, int *flag); - -/* - * ----------------------------------------------------------------- - * The following function returns the name of the constant - * associated with a CVDLS return flag - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT char *CVDlsGetReturnFlagName(int flag); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/amuse/community/secularmultiple/src/cvode/cvode_direct_impl.h b/src/amuse/community/secularmultiple/src/cvode/cvode_direct_impl.h deleted file mode 100755 index 62e95d079f..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/cvode_direct_impl.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.5 $ - * $Date: 2008/04/18 19:42:39 $ - * ----------------------------------------------------------------- - * Programmer: Radu Serban @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2006, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * Common implementation header file for the CVDLS linear solvers. - * ----------------------------------------------------------------- - */ - -#ifndef _CVDLS_IMPL_H -#define _CVDLS_IMPL_H - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -#include "cvode_direct.h" - -/* - * ----------------------------------------------------------------- - * CVDLS solver constants - * ----------------------------------------------------------------- - * CVD_MSBJ maximum number of steps between Jacobian evaluations - * CVD_DGMAX maximum change in gamma between Jacobian evaluations - * ----------------------------------------------------------------- - */ - -#define CVD_MSBJ 50 -#define CVD_DGMAX RCONST(0.2) - -/* - * ----------------------------------------------------------------- - * Types : CVDlsMemRec, CVDlsMem - * ----------------------------------------------------------------- - * CVDlsMem is pointer to a CVDlsMemRec structure. - * ----------------------------------------------------------------- - */ - -typedef struct CVDlsMemRec { - - int d_type; /* SUNDIALS_DENSE or SUNDIALS_BAND */ - - int d_n; /* problem dimension */ - - int d_ml; /* lower bandwidth of Jacobian */ - int d_mu; /* upper bandwidth of Jacobian */ - int d_smu; /* upper bandwith of M = MIN(N-1,d_mu+d_ml) */ - - booleantype d_jacDQ; /* TRUE if using internal DQ Jacobian approx. */ - CVDlsDenseJacFn d_djac; /* dense Jacobian routine to be called */ - CVDlsBandJacFn d_bjac; /* band Jacobian routine to be called */ - void *d_J_data; /* user data is passed to djac or bjac */ - - DlsMat d_M; /* M = I - gamma * df/dy */ - DlsMat d_savedJ; /* savedJ = old Jacobian */ - - int *d_pivots; /* pivots = pivot array for PM = LU */ - - long int d_nstlj; /* nstlj = nst at last Jacobian eval. */ - - long int d_nje; /* nje = no. of calls to jac */ - - long int d_nfeDQ; /* no. of calls to f due to DQ Jacobian approx. */ - - int d_last_flag; /* last error return flag */ - -} *CVDlsMem; - -/* - * ----------------------------------------------------------------- - * Prototypes of internal functions - * ----------------------------------------------------------------- - */ - -int cvDlsDenseDQJac(int N, realtype t, - N_Vector y, N_Vector fy, - DlsMat Jac, void *data, - N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); - -int cvDlsBandDQJac(int N, int mupper, int mlower, - realtype t, N_Vector y, N_Vector fy, - DlsMat Jac, void *data, - N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); - - -/* - * ----------------------------------------------------------------- - * Error Messages - * ----------------------------------------------------------------- - */ - -#define MSGD_CVMEM_NULL "Integrator memory is NULL." -#define MSGD_BAD_NVECTOR "A required vector operation is not implemented." -#define MSGD_BAD_SIZES "Illegal bandwidth parameter(s). Must have 0 <= ml, mu <= N-1." -#define MSGD_MEM_FAIL "A memory request failed." -#define MSGD_LMEM_NULL "Linear solver memory is NULL." -#define MSGD_JACFUNC_FAILED "The Jacobian routine failed in an unrecoverable manner." - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/amuse/community/secularmultiple/src/cvode/cvode_impl.h b/src/amuse/community/secularmultiple/src/cvode/cvode_impl.h deleted file mode 100755 index e69a473798..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/cvode_impl.h +++ /dev/null @@ -1,515 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.13 $ - * $Date: 2007/11/26 16:19:59 $ - * ----------------------------------------------------------------- - * Programmer(s): Scott D. Cohen, Alan C. Hindmarsh, Radu Serban - * and Dan Shumaker @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * Implementation header file for the main CVODE integrator. - * ----------------------------------------------------------------- - */ - -#ifndef _CVODE_IMPL_H -#define _CVODE_IMPL_H - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -#include - -#include "cvode.h" - -/* - * ================================================================= - * M A I N I N T E G R A T O R M E M O R Y B L O C K - * ================================================================= - */ - -/* Basic CVODE constants */ - -#define ADAMS_Q_MAX 12 /* max value of q for lmm == ADAMS */ -#define BDF_Q_MAX 5 /* max value of q for lmm == BDF */ -#define Q_MAX ADAMS_Q_MAX /* max value of q for either lmm */ -#define L_MAX (Q_MAX+1) /* max value of L for either lmm */ -#define NUM_TESTS 5 /* number of error test quantities */ - -#define HMIN_DEFAULT RCONST(0.0) /* hmin default value */ -#define HMAX_INV_DEFAULT RCONST(0.0) /* hmax_inv default value */ -#define MXHNIL_DEFAULT 10 /* mxhnil default value */ -#define MXSTEP_DEFAULT 500 /* mxstep default value */ - -/* - * ----------------------------------------------------------------- - * Types : struct CVodeMemRec, CVodeMem - * ----------------------------------------------------------------- - * The type CVodeMem is type pointer to struct CVodeMemRec. - * This structure contains fields to keep track of problem state. - * ----------------------------------------------------------------- - */ - -typedef struct CVodeMemRec { - - realtype cv_uround; /* machine unit roundoff */ - - /*-------------------------- - Problem Specification Data - --------------------------*/ - - CVRhsFn cv_f; /* y' = f(t,y(t)) */ - void *cv_user_data; /* user pointer passed to f */ - int cv_lmm; /* lmm = CV_ADAMS or CV_BDF */ - int cv_iter; /* iter = CV_FUNCTIONAL or CV_NEWTON */ - int cv_itol; /* itol = CV_SS, CV_SV, CV_WF, CV_NN */ - - realtype cv_reltol; /* relative tolerance */ - realtype cv_Sabstol; /* scalar absolute tolerance */ - N_Vector cv_Vabstol; /* vector absolute tolerance */ - booleantype cv_user_efun; /* TRUE if user sets efun */ - CVEwtFn cv_efun; /* function to set ewt */ - void *cv_e_data; /* user pointer passed to efun */ - - /*----------------------- - Nordsieck History Array - -----------------------*/ - - N_Vector cv_zn[L_MAX]; /* Nordsieck array, of size N x (q+1). - zn[j] is a vector of length N (j=0,...,q) - zn[j] = [1/factorial(j)] * h^j * (jth - derivative of the interpolating polynomial */ - - /*-------------------------- - other vectors of length N - -------------------------*/ - - N_Vector cv_ewt; /* error weight vector */ - N_Vector cv_y; /* y is used as temporary storage by the solver - The memory is provided by the user to CVode - where the vector is named yout. */ - N_Vector cv_acor; /* In the context of the solution of the nonlinear - equation, acor = y_n(m) - y_n(0). On return, - this vector is scaled to give the est. local err. */ - N_Vector cv_tempv; /* temporary storage vector */ - N_Vector cv_ftemp; /* temporary storage vector */ - - /*----------------- - Tstop information - -----------------*/ - - booleantype cv_tstopset; - realtype cv_tstop; - - /*--------- - Step Data - ---------*/ - - int cv_q; /* current order */ - int cv_qprime; /* order to be used on the next step - = q-1, q, or q+1 */ - int cv_next_q; /* order to be used on the next step */ - int cv_qwait; /* number of internal steps to wait before - considering a change in q */ - int cv_L; /* L = q + 1 */ - - realtype cv_hin; /* initial step size */ - realtype cv_h; /* current step size */ - realtype cv_hprime; /* step size to be used on the next step */ - realtype cv_next_h; /* step size to be used on the next step */ - realtype cv_eta; /* eta = hprime / h */ - realtype cv_hscale; /* value of h used in zn */ - realtype cv_tn; /* current internal value of t */ - realtype cv_tretlast; /* value of tret last returned by CVode */ - - realtype cv_tau[L_MAX+1]; /* array of previous q+1 successful step - sizes indexed from 1 to q+1 */ - realtype cv_tq[NUM_TESTS+1]; /* array of test quantities indexed from - 1 to NUM_TESTS(=5) */ - realtype cv_l[L_MAX]; /* coefficients of l(x) (degree q poly) */ - - realtype cv_rl1; /* the scalar 1/l[1] */ - realtype cv_gamma; /* gamma = h * rl1 */ - realtype cv_gammap; /* gamma at the last setup call */ - realtype cv_gamrat; /* gamma / gammap */ - - realtype cv_crate; /* estimated corrector convergence rate */ - realtype cv_acnrm; /* | acor | wrms */ - realtype cv_nlscoef; /* coeficient in nonlinear convergence test */ - int cv_mnewt; /* Newton iteration counter */ - - /*------ - Limits - ------*/ - - int cv_qmax; /* q <= qmax */ - long int cv_mxstep; /* maximum number of internal steps for one user call */ - int cv_maxcor; /* maximum number of corrector iterations for the - solution of the nonlinear equation */ - int cv_mxhnil; /* maximum number of warning messages issued to the - user that t + h == t for the next internal step */ - int cv_maxnef; /* maximum number of error test failures */ - int cv_maxncf; /* maximum number of nonlinear convergence failures */ - - realtype cv_hmin; /* |h| >= hmin */ - realtype cv_hmax_inv; /* |h| <= 1/hmax_inv */ - realtype cv_etamax; /* eta <= etamax */ - - /*-------- - Counters - --------*/ - - long int cv_nst; /* number of internal steps taken */ - long int cv_nfe; /* number of f calls */ - long int cv_ncfn; /* number of corrector convergence failures */ - long int cv_netf; /* number of error test failures */ - long int cv_nni; /* number of Newton iterations performed */ - long int cv_nsetups; /* number of setup calls */ - int cv_nhnil; /* number of messages issued to the user that - t + h == t for the next iternal step */ - - realtype cv_etaqm1; /* ratio of new to old h for order q-1 */ - realtype cv_etaq; /* ratio of new to old h for order q */ - realtype cv_etaqp1; /* ratio of new to old h for order q+1 */ - - /*---------------------------- - Space requirements for CVODE - ----------------------------*/ - - long int cv_lrw1; /* no. of realtype words in 1 N_Vector */ - long int cv_liw1; /* no. of integer words in 1 N_Vector */ - long int cv_lrw; /* no. of realtype words in CVODE work vectors */ - long int cv_liw; /* no. of integer words in CVODE work vectors */ - - /*------------------ - Linear Solver Data - ------------------*/ - - /* Linear Solver functions to be called */ - - int (*cv_linit)(struct CVodeMemRec *cv_mem); - - int (*cv_lsetup)(struct CVodeMemRec *cv_mem, int convfail, N_Vector ypred, - N_Vector fpred, booleantype *jcurPtr, N_Vector vtemp1, - N_Vector vtemp2, N_Vector vtemp3); - - int (*cv_lsolve)(struct CVodeMemRec *cv_mem, N_Vector b, N_Vector weight, - N_Vector ycur, N_Vector fcur); - - void (*cv_lfree)(struct CVodeMemRec *cv_mem); - - /* Linear Solver specific memory */ - - void *cv_lmem; - - /*------------ - Saved Values - ------------*/ - - int cv_qu; /* last successful q value used */ - long int cv_nstlp; /* step number of last setup call */ - realtype cv_h0u; /* actual initial stepsize */ - realtype cv_hu; /* last successful h value used */ - realtype cv_saved_tq5; /* saved value of tq[5] */ - booleantype cv_jcur; /* is Jacobian info. for lin. solver current? */ - realtype cv_tolsf; /* tolerance scale factor */ - int cv_qmax_alloc; /* value of qmax used when allocating memory */ - int cv_indx_acor; /* index of the zn vector with saved acor */ - booleantype cv_setupNonNull; /* does setup do anything? */ - - booleantype cv_VabstolMallocDone; - booleantype cv_MallocDone; - - /*------------------------------------------- - Error handler function and error ouput file - -------------------------------------------*/ - - CVErrHandlerFn cv_ehfun; /* error messages are handled by ehfun */ - void *cv_eh_data; /* data pointer passed to ehfun */ - FILE *cv_errfp; /* CVODE error messages are sent to errfp */ - - /*------------------------- - Stability Limit Detection - -------------------------*/ - - booleantype cv_sldeton; /* is Stability Limit Detection on? */ - realtype cv_ssdat[6][4]; /* scaled data array for STALD */ - int cv_nscon; /* counter for STALD method */ - long int cv_nor; /* counter for number of order reductions */ - - /*---------------- - Rootfinding Data - ----------------*/ - - CVRootFn cv_gfun; /* function g for roots sought */ - int cv_nrtfn; /* number of components of g */ - int *cv_iroots; /* array for root information */ - int *cv_rootdir; /* array specifying direction of zero-crossing */ - realtype cv_tlo; /* nearest endpoint of interval in root search */ - realtype cv_thi; /* farthest endpoint of interval in root search */ - realtype cv_trout; /* t value returned by rootfinding routine */ - realtype *cv_glo; /* saved array of g values at t = tlo */ - realtype *cv_ghi; /* saved array of g values at t = thi */ - realtype *cv_grout; /* array of g values at t = trout */ - realtype cv_toutc; /* copy of tout (if NORMAL mode) */ - realtype cv_ttol; /* tolerance on root location */ - int cv_taskc; /* copy of parameter itask */ - int cv_irfnd; /* flag showing whether last step had a root */ - long int cv_nge; /* counter for g evaluations */ - booleantype *cv_gactive; /* array with active/inactive event functions */ - int cv_mxgnull; /* number of warning messages about possible g==0 */ - - -} *CVodeMem; - -/* - * ================================================================= - * I N T E R F A C E T O L I N E A R S O L V E R S - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * Communication between CVODE and a CVODE Linear Solver - * ----------------------------------------------------------------- - * convfail (input to cv_lsetup) - * - * CV_NO_FAILURES : Either this is the first cv_setup call for this - * step, or the local error test failed on the - * previous attempt at this step (but the Newton - * iteration converged). - * - * CV_FAIL_BAD_J : This value is passed to cv_lsetup if - * - * (a) The previous Newton corrector iteration - * did not converge and the linear solver's - * setup routine indicated that its Jacobian- - * related data is not current - * or - * (b) During the previous Newton corrector - * iteration, the linear solver's solve routine - * failed in a recoverable manner and the - * linear solver's setup routine indicated that - * its Jacobian-related data is not current. - * - * CV_FAIL_OTHER : During the current internal step try, the - * previous Newton iteration failed to converge - * even though the linear solver was using current - * Jacobian-related data. - * ----------------------------------------------------------------- - */ - -/* Constants for convfail (input to cv_lsetup) */ - -#define CV_NO_FAILURES 0 -#define CV_FAIL_BAD_J 1 -#define CV_FAIL_OTHER 2 - -/* - * ----------------------------------------------------------------- - * int (*cv_linit)(CVodeMem cv_mem); - * ----------------------------------------------------------------- - * The purpose of cv_linit is to complete initializations for a - * specific linear solver, such as counters and statistics. - * An LInitFn should return 0 if it has successfully initialized the - * CVODE linear solver and a negative value otherwise. - * If an error does occur, an appropriate message should be sent to - * the error handler function. - * ----------------------------------------------------------------- - */ - -/* - * ----------------------------------------------------------------- - * int (*cv_lsetup)(CVodeMem cv_mem, int convfail, N_Vector ypred, - * N_Vector fpred, booleantype *jcurPtr, - * N_Vector vtemp1, N_Vector vtemp2, - * N_Vector vtemp3); - * ----------------------------------------------------------------- - * The job of cv_lsetup is to prepare the linear solver for - * subsequent calls to cv_lsolve. It may recompute Jacobian- - * related data is it deems necessary. Its parameters are as - * follows: - * - * cv_mem - problem memory pointer of type CVodeMem. See the - * typedef earlier in this file. - * - * convfail - a flag to indicate any problem that occurred during - * the solution of the nonlinear equation on the - * current time step for which the linear solver is - * being used. This flag can be used to help decide - * whether the Jacobian data kept by a CVODE linear - * solver needs to be updated or not. - * Its possible values have been documented above. - * - * ypred - the predicted y vector for the current CVODE internal - * step. - * - * fpred - f(tn, ypred). - * - * jcurPtr - a pointer to a boolean to be filled in by cv_lsetup. - * The function should set *jcurPtr=TRUE if its Jacobian - * data is current after the call and should set - * *jcurPtr=FALSE if its Jacobian data is not current. - * Note: If cv_lsetup calls for re-evaluation of - * Jacobian data (based on convfail and CVODE state - * data), it should return *jcurPtr=TRUE always; - * otherwise an infinite loop can result. - * - * vtemp1 - temporary N_Vector provided for use by cv_lsetup. - * - * vtemp3 - temporary N_Vector provided for use by cv_lsetup. - * - * vtemp3 - temporary N_Vector provided for use by cv_lsetup. - * - * The cv_lsetup routine should return 0 if successful, a positive - * value for a recoverable error, and a negative value for an - * unrecoverable error. - * ----------------------------------------------------------------- - */ - -/* - * ----------------------------------------------------------------- - * int (*cv_lsolve)(CVodeMem cv_mem, N_Vector b, N_Vector weight, - * N_Vector ycur, N_Vector fcur); - * ----------------------------------------------------------------- - * cv_lsolve must solve the linear equation P x = b, where - * P is some approximation to (I - gamma J), J = (df/dy)(tn,ycur) - * and the RHS vector b is input. The N-vector ycur contains - * the solver's current approximation to y(tn) and the vector - * fcur contains the N_Vector f(tn,ycur). The solution is to be - * returned in the vector b. cv_lsolve returns a positive value - * for a recoverable error and a negative value for an - * unrecoverable error. Success is indicated by a 0 return value. - * ----------------------------------------------------------------- - */ - -/* - * ----------------------------------------------------------------- - * void (*cv_lfree)(CVodeMem cv_mem); - * ----------------------------------------------------------------- - * cv_lfree should free up any memory allocated by the linear - * solver. This routine is called once a problem has been - * completed and the linear solver is no longer needed. - * ----------------------------------------------------------------- - */ - -/* - * ================================================================= - * C V O D E I N T E R N A L F U N C T I O N S - * ================================================================= - */ - -/* Prototype of internal ewtSet function */ - -int CVEwtSet(N_Vector ycur, N_Vector weight, void *data); - -/* High level error handler */ - -void CVProcessError(CVodeMem cv_mem, - int error_code, const char *module, const char *fname, - const char *msgfmt, ...); - -/* Prototype of internal errHandler function */ - -void CVErrHandler(int error_code, const char *module, const char *function, - char *msg, void *data); - -/* - * ================================================================= - * C V O D E E R R O R M E S S A G E S - * ================================================================= - */ - -#if defined(SUNDIALS_EXTENDED_PRECISION) - -#define MSG_TIME "t = %Lg" -#define MSG_TIME_H "t = %Lg and h = %Lg" -#define MSG_TIME_INT "t = %Lg is not between tcur - hu = %Lg and tcur = %Lg." -#define MSG_TIME_TOUT "tout = %Lg" -#define MSG_TIME_TSTOP "tstop = %Lg" - -#elif defined(SUNDIALS_DOUBLE_PRECISION) - -#define MSG_TIME "t = %lg" -#define MSG_TIME_H "t = %lg and h = %lg" -#define MSG_TIME_INT "t = %lg is not between tcur - hu = %lg and tcur = %lg." -#define MSG_TIME_TOUT "tout = %lg" -#define MSG_TIME_TSTOP "tstop = %lg" - -#else - -#define MSG_TIME "t = %g" -#define MSG_TIME_H "t = %g and h = %g" -#define MSG_TIME_INT "t = %g is not between tcur - hu = %g and tcur = %g." -#define MSG_TIME_TOUT "tout = %g" -#define MSG_TIME_TSTOP "tstop = %g" - -#endif - -/* Initialization and I/O error messages */ - -#define MSGCV_NO_MEM "cvode_mem = NULL illegal." -#define MSGCV_CVMEM_FAIL "Allocation of cvode_mem failed." -#define MSGCV_MEM_FAIL "A memory request failed." -#define MSGCV_BAD_LMM "Illegal value for lmm. The legal values are CV_ADAMS and CV_BDF." -#define MSGCV_BAD_ITER "Illegal value for iter. The legal values are CV_FUNCTIONAL and CV_NEWTON." -#define MSGCV_NO_MALLOC "Attempt to call before CVodeInit." -#define MSGCV_NEG_MAXORD "maxord <= 0 illegal." -#define MSGCV_BAD_MAXORD "Illegal attempt to increase maximum method order." -#define MSGCV_SET_SLDET "Attempt to use stability limit detection with the CV_ADAMS method illegal." -#define MSGCV_NEG_HMIN "hmin < 0 illegal." -#define MSGCV_NEG_HMAX "hmax < 0 illegal." -#define MSGCV_BAD_HMIN_HMAX "Inconsistent step size limits: hmin > hmax." -#define MSGCV_BAD_RELTOL "reltol < 0 illegal." -#define MSGCV_BAD_ABSTOL "abstol has negative component(s) (illegal)." -#define MSGCV_NULL_ABSTOL "abstol = NULL illegal." -#define MSGCV_NULL_Y0 "y0 = NULL illegal." -#define MSGCV_NULL_F "f = NULL illegal." -#define MSGCV_NULL_G "g = NULL illegal." -#define MSGCV_BAD_NVECTOR "A required vector operation is not implemented." -#define MSGCV_BAD_K "Illegal value for k." -#define MSGCV_NULL_DKY "dky = NULL illegal." -#define MSGCV_BAD_T "Illegal value for t." MSG_TIME_INT -#define MSGCV_NO_ROOT "Rootfinding was not initialized." - -/* CVode Error Messages */ - -#define MSGCV_NO_TOLS "No integration tolerances have been specified." -#define MSGCV_LSOLVE_NULL "The linear solver's solve routine is NULL." -#define MSGCV_YOUT_NULL "yout = NULL illegal." -#define MSGCV_TRET_NULL "tret = NULL illegal." -#define MSGCV_BAD_EWT "Initial ewt has component(s) equal to zero (illegal)." -#define MSGCV_EWT_NOW_BAD "At " MSG_TIME ", a component of ewt has become <= 0." -#define MSGCV_BAD_ITASK "Illegal value for itask." -#define MSGCV_BAD_H0 "h0 and tout - t0 inconsistent." -#define MSGCV_BAD_TOUT "Trouble interpolating at " MSG_TIME_TOUT ". tout too far back in direction of integration" -#define MSGCV_EWT_FAIL "The user-provide EwtSet function failed." -#define MSGCV_EWT_NOW_FAIL "At " MSG_TIME ", the user-provide EwtSet function failed." -#define MSGCV_LINIT_FAIL "The linear solver's init routine failed." -#define MSGCV_HNIL_DONE "The above warning has been issued mxhnil times and will not be issued again for this problem." -#define MSGCV_TOO_CLOSE "tout too close to t0 to start integration." -#define MSGCV_MAX_STEPS "At " MSG_TIME ", mxstep steps taken before reaching tout." -#define MSGCV_TOO_MUCH_ACC "At " MSG_TIME ", too much accuracy requested." -#define MSGCV_HNIL "Internal " MSG_TIME_H " are such that t + h = t on the next step. The solver will continue anyway." -#define MSGCV_ERR_FAILS "At " MSG_TIME_H ", the error test failed repeatedly or with |h| = hmin." -#define MSGCV_CONV_FAILS "At " MSG_TIME_H ", the corrector convergence test failed repeatedly or with |h| = hmin." -#define MSGCV_SETUP_FAILED "At " MSG_TIME ", the setup routine failed in an unrecoverable manner." -#define MSGCV_SOLVE_FAILED "At " MSG_TIME ", the solve routine failed in an unrecoverable manner." -#define MSGCV_RHSFUNC_FAILED "At " MSG_TIME ", the right-hand side routine failed in an unrecoverable manner." -#define MSGCV_RHSFUNC_UNREC "At " MSG_TIME ", the right-hand side failed in a recoverable manner, but no recovery is possible." -#define MSGCV_RHSFUNC_REPTD "At " MSG_TIME " repeated recoverable right-hand side function errors." -#define MSGCV_RHSFUNC_FIRST "The right-hand side routine failed at the first call." -#define MSGCV_RTFUNC_FAILED "At " MSG_TIME ", the rootfinding routine failed in an unrecoverable manner." -#define MSGCV_CLOSE_ROOTS "Root found at and very near " MSG_TIME "." -#define MSGCV_BAD_TSTOP "The value " MSG_TIME_TSTOP " is behind current " MSG_TIME " in the direction of integration." -#define MSGCV_INACTIVE_ROOTS "At the end of the first step, there are still some root functions identically 0. This warning will not be issued again." - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/amuse/community/secularmultiple/src/cvode/cvode_io.c b/src/amuse/community/secularmultiple/src/cvode/cvode_io.c deleted file mode 100755 index 713e36972b..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/cvode_io.c +++ /dev/null @@ -1,1129 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.11 $ - * $Date: 2007/11/26 16:19:59 $ - * ----------------------------------------------------------------- - * Programmer(s): Alan C. Hindmarsh and Radu Serban @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the implementation file for the optional input and output - * functions for the CVODE solver. - * ----------------------------------------------------------------- - */ - -#include -#include - -#include "cvode_impl.h" -#include "sundials_types.h" - -#define ZERO RCONST(0.0) -#define ONE RCONST(1.0) - -#define lrw (cv_mem->cv_lrw) -#define liw (cv_mem->cv_liw) -#define lrw1 (cv_mem->cv_lrw1) -#define liw1 (cv_mem->cv_liw1) - -/* - * ================================================================= - * CVODE optional input functions - * ================================================================= - */ - -/* - * CVodeSetErrHandlerFn - * - * Specifies the error handler function - */ - -int CVodeSetErrHandlerFn(void *cvode_mem, CVErrHandlerFn ehfun, void *eh_data) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetErrHandlerFn", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - cv_mem->cv_ehfun = ehfun; - cv_mem->cv_eh_data = eh_data; - - return(CV_SUCCESS); -} - -/* - * CVodeSetErrFile - * - * Specifies the FILE pointer for output (NULL means no messages) - */ - -int CVodeSetErrFile(void *cvode_mem, FILE *errfp) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetErrFile", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - cv_mem->cv_errfp = errfp; - - return(CV_SUCCESS); -} - -/* - * CVodeSetIterType - * - * Specifies the iteration type (CV_FUNCTIONAL or CV_NEWTON) - */ - -int CVodeSetIterType(void *cvode_mem, int iter) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetIterType", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - if ((iter != CV_FUNCTIONAL) && (iter != CV_NEWTON)) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSetIterType", MSGCV_BAD_ITER); - return (CV_ILL_INPUT); - } - - cv_mem->cv_iter = iter; - - return(CV_SUCCESS); -} - -/* - * CVodeSetUserData - * - * Specifies the user data pointer for f - */ - -int CVodeSetUserData(void *cvode_mem, void *user_data) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetUserData", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - cv_mem->cv_user_data = user_data; - - return(CV_SUCCESS); -} - -/* - * CVodeSetMaxOrd - * - * Specifies the maximum method order - */ - -int CVodeSetMaxOrd(void *cvode_mem, int maxord) -{ - CVodeMem cv_mem; - int qmax_alloc; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetMaxOrd", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - if (maxord <= 0) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSetMaxOrd", MSGCV_NEG_MAXORD); - return(CV_ILL_INPUT); - } - - /* Cannot increase maximum order beyond the value that - was used when allocating memory */ - qmax_alloc = cv_mem->cv_qmax_alloc; - - if (maxord > qmax_alloc) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSetMaxOrd", MSGCV_BAD_MAXORD); - return(CV_ILL_INPUT); - } - - cv_mem->cv_qmax = maxord; - - return(CV_SUCCESS); -} - -/* - * CVodeSetMaxNumSteps - * - * Specifies the maximum number of integration steps - */ - -int CVodeSetMaxNumSteps(void *cvode_mem, long int mxsteps) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetMaxNumSteps", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - /* Passing mxsteps=0 sets the default. Passing mxsteps<0 disables the test. */ - - if (mxsteps == 0) - cv_mem->cv_mxstep = MXSTEP_DEFAULT; - else - cv_mem->cv_mxstep = mxsteps; - - return(CV_SUCCESS); -} - -/* - * CVodeSetMaxHnilWarns - * - * Specifies the maximum number of warnings for small h - */ - -int CVodeSetMaxHnilWarns(void *cvode_mem, int mxhnil) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetMaxHnilWarns", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - cv_mem->cv_mxhnil = mxhnil; - - return(CV_SUCCESS); -} - -/* - *CVodeSetStabLimDet - * - * Turns on/off the stability limit detection algorithm - */ - -int CVodeSetStabLimDet(void *cvode_mem, booleantype sldet) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetStabLimDet", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - if( sldet && (cv_mem->cv_lmm != CV_BDF) ) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSetStabLimDet", MSGCV_SET_SLDET); - return(CV_ILL_INPUT); - } - - cv_mem->cv_sldeton = sldet; - - return(CV_SUCCESS); -} - -/* - * CVodeSetInitStep - * - * Specifies the initial step size - */ - -int CVodeSetInitStep(void *cvode_mem, realtype hin) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetInitStep", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - cv_mem->cv_hin = hin; - - return(CV_SUCCESS); -} - -/* - * CVodeSetMinStep - * - * Specifies the minimum step size - */ - -int CVodeSetMinStep(void *cvode_mem, realtype hmin) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetMinStep", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - if (hmin<0) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSetMinStep", MSGCV_NEG_HMIN); - return(CV_ILL_INPUT); - } - - /* Passing 0 sets hmin = zero */ - if (hmin == ZERO) { - cv_mem->cv_hmin = HMIN_DEFAULT; - return(CV_SUCCESS); - } - - if (hmin * cv_mem->cv_hmax_inv > ONE) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSetMinStep", MSGCV_BAD_HMIN_HMAX); - return(CV_ILL_INPUT); - } - - cv_mem->cv_hmin = hmin; - - return(CV_SUCCESS); -} - -/* - * CVodeSetMaxStep - * - * Specifies the maximum step size - */ - -int CVodeSetMaxStep(void *cvode_mem, realtype hmax) -{ - realtype hmax_inv; - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetMaxStep", MSGCV_NO_MEM); - return (CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - if (hmax < 0) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSetMaxStep", MSGCV_NEG_HMAX); - return(CV_ILL_INPUT); - } - - /* Passing 0 sets hmax = infinity */ - if (hmax == ZERO) { - cv_mem->cv_hmax_inv = HMAX_INV_DEFAULT; - return(CV_SUCCESS); - } - - hmax_inv = ONE/hmax; - if (hmax_inv * cv_mem->cv_hmin > ONE) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSetMaxStep", MSGCV_BAD_HMIN_HMAX); - return(CV_ILL_INPUT); - } - - cv_mem->cv_hmax_inv = hmax_inv; - - return(CV_SUCCESS); -} - -/* - * CVodeSetStopTime - * - * Specifies the time beyond which the integration is not to proceed. - */ - -int CVodeSetStopTime(void *cvode_mem, realtype tstop) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetStopTime", MSGCV_NO_MEM); - return (CV_MEM_NULL); - } - cv_mem = (CVodeMem) cvode_mem; - - /* If CVode was called at least once, test if tstop is legal - * (i.e. if it was not already passed). - * If CVodeSetStopTime is called before the first call to CVode, - * tstop will be checked in CVode. */ - if (cv_mem->cv_nst > 0) { - - if ( (tstop - cv_mem->cv_tn) * cv_mem->cv_h < ZERO ) { - CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeSetStopTime", MSGCV_BAD_TSTOP, cv_mem->cv_tn); - return(CV_ILL_INPUT); - } - - } - - cv_mem->cv_tstop = tstop; - cv_mem->cv_tstopset = TRUE; - - return(CV_SUCCESS); -} - -/* - * CVodeSetMaxErrTestFails - * - * Specifies the maximum number of error test failures during one - * step try. - */ - -int CVodeSetMaxErrTestFails(void *cvode_mem, int maxnef) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetMaxErrTestFails", MSGCV_NO_MEM); - return (CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - cv_mem->cv_maxnef = maxnef; - - return(CV_SUCCESS); -} - -/* - * CVodeSetMaxConvFails - * - * Specifies the maximum number of nonlinear convergence failures - * during one step try. - */ - -int CVodeSetMaxConvFails(void *cvode_mem, int maxncf) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetMaxConvFails", MSGCV_NO_MEM); - return (CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - cv_mem->cv_maxncf = maxncf; - - return(CV_SUCCESS); -} - -/* - * CVodeSetMaxNonlinIters - * - * Specifies the maximum number of nonlinear iterations during - * one solve. - */ - -int CVodeSetMaxNonlinIters(void *cvode_mem, int maxcor) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetMaxNonlinIters", MSGCV_NO_MEM); - return (CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - cv_mem->cv_maxcor = maxcor; - - return(CV_SUCCESS); -} - -/* - * CVodeSetNonlinConvCoef - * - * Specifies the coeficient in the nonlinear solver convergence - * test - */ - -int CVodeSetNonlinConvCoef(void *cvode_mem, realtype nlscoef) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetNonlinConvCoef", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - cv_mem->cv_nlscoef = nlscoef; - - return(CV_SUCCESS); -} - -/* - * CVodeSetRootDirection - * - * Specifies the direction of zero-crossings to be monitored. - * The default is to monitor both crossings. - */ - -int CVodeSetRootDirection(void *cvode_mem, int *rootdir) -{ - CVodeMem cv_mem; - int i, nrt; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetRootDirection", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - nrt = cv_mem->cv_nrtfn; - if (nrt==0) { - CVProcessError(NULL, CV_ILL_INPUT, "CVODE", "CVodeSetRootDirection", MSGCV_NO_ROOT); - return(CV_ILL_INPUT); - } - - for(i=0; icv_rootdir[i] = rootdir[i]; - - return(CV_SUCCESS); -} - -/* - * CVodeSetNoInactiveRootWarn - * - * Disables issuing a warning if some root function appears - * to be identically zero at the beginning of the integration - */ - -int CVodeSetNoInactiveRootWarn(void *cvode_mem) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeSetNoInactiveRootWarn", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - cv_mem->cv_mxgnull = 0; - - return(CV_SUCCESS); -} - - -/* - * ================================================================= - * CVODE optional output functions - * ================================================================= - */ - -/* - * Readability constants - */ - -#define nst (cv_mem->cv_nst) -#define nfe (cv_mem->cv_nfe) -#define ncfn (cv_mem->cv_ncfn) -#define netf (cv_mem->cv_netf) -#define nni (cv_mem->cv_nni) -#define nsetups (cv_mem->cv_nsetups) -#define qu (cv_mem->cv_qu) -#define next_q (cv_mem->cv_next_q) -#define ewt (cv_mem->cv_ewt) -#define hu (cv_mem->cv_hu) -#define next_h (cv_mem->cv_next_h) -#define h0u (cv_mem->cv_h0u) -#define tolsf (cv_mem->cv_tolsf) -#define acor (cv_mem->cv_acor) -#define lrw (cv_mem->cv_lrw) -#define liw (cv_mem->cv_liw) -#define nge (cv_mem->cv_nge) -#define iroots (cv_mem->cv_iroots) -#define nor (cv_mem->cv_nor) -#define sldeton (cv_mem->cv_sldeton) -#define tn (cv_mem->cv_tn) -#define efun (cv_mem->cv_efun) - -/* - * CVodeGetNumSteps - * - * Returns the current number of integration steps - */ - -int CVodeGetNumSteps(void *cvode_mem, long int *nsteps) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetNumSteps", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *nsteps = nst; - - return(CV_SUCCESS); -} - -/* - * CVodeGetNumRhsEvals - * - * Returns the current number of calls to f - */ - -int CVodeGetNumRhsEvals(void *cvode_mem, long int *nfevals) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetNumRhsEvals", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *nfevals = nfe; - - return(CV_SUCCESS); -} - -/* - * CVodeGetNumLinSolvSetups - * - * Returns the current number of calls to the linear solver setup routine - */ - -int CVodeGetNumLinSolvSetups(void *cvode_mem, long int *nlinsetups) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetNumLinSolvSetups", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *nlinsetups = nsetups; - - return(CV_SUCCESS); -} - -/* - * CVodeGetNumErrTestFails - * - * Returns the current number of error test failures - */ - -int CVodeGetNumErrTestFails(void *cvode_mem, long int *netfails) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetNumErrTestFails", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *netfails = netf; - - return(CV_SUCCESS); -} - -/* - * CVodeGetLastOrder - * - * Returns the order on the last succesful step - */ - -int CVodeGetLastOrder(void *cvode_mem, int *qlast) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetLastOrder", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *qlast = qu; - - return(CV_SUCCESS); -} - -/* - * CVodeGetCurrentOrder - * - * Returns the order to be attempted on the next step - */ - -int CVodeGetCurrentOrder(void *cvode_mem, int *qcur) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetCurrentOrder", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *qcur = next_q; - - return(CV_SUCCESS); -} - -/* - * CVodeGetNumStabLimOrderReds - * - * Returns the number of order reductions triggered by the stability - * limit detection algorithm - */ - -int CVodeGetNumStabLimOrderReds(void *cvode_mem, long int *nslred) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetNumStabLimOrderReds", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - if (sldeton==FALSE) - *nslred = 0; - else - *nslred = nor; - - return(CV_SUCCESS); -} - -/* - * CVodeGetActualInitStep - * - * Returns the step size used on the first step - */ - -int CVodeGetActualInitStep(void *cvode_mem, realtype *hinused) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetActualInitStep", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *hinused = h0u; - - return(CV_SUCCESS); -} - -/* - * CVodeGetLastStep - * - * Returns the step size used on the last successful step - */ - -int CVodeGetLastStep(void *cvode_mem, realtype *hlast) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetLastStep", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *hlast = hu; - - return(CV_SUCCESS); -} - -/* - * CVodeGetCurrentStep - * - * Returns the step size to be attempted on the next step - */ - -int CVodeGetCurrentStep(void *cvode_mem, realtype *hcur) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetCurrentStep", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *hcur = next_h; - - return(CV_SUCCESS); -} - -/* - * CVodeGetCurrentTime - * - * Returns the current value of the independent variable - */ - -int CVodeGetCurrentTime(void *cvode_mem, realtype *tcur) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetCurrentTime", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *tcur = tn; - - return(CV_SUCCESS); -} - -/* - * CVodeGetTolScaleFactor - * - * Returns a suggested factor for scaling tolerances - */ - -int CVodeGetTolScaleFactor(void *cvode_mem, realtype *tolsfact) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetTolScaleFactor", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *tolsfact = tolsf; - - return(CV_SUCCESS); -} - -/* - * CVodeGetErrWeights - * - * This routine returns the current weight vector. - */ - -int CVodeGetErrWeights(void *cvode_mem, N_Vector eweight) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetErrWeights", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - N_VScale(ONE, ewt, eweight); - - return(CV_SUCCESS); -} - -/* - * CVodeGetEstLocalErrors - * - * Returns an estimate of the local error - */ - -int CVodeGetEstLocalErrors(void *cvode_mem, N_Vector ele) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetEstLocalErrors", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - N_VScale(ONE, acor, ele); - - return(CV_SUCCESS); -} - -/* - * CVodeGetWorkSpace - * - * Returns integrator work space requirements - */ - -int CVodeGetWorkSpace(void *cvode_mem, long int *lenrw, long int *leniw) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetWorkSpace", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *leniw = liw; - *lenrw = lrw; - - return(CV_SUCCESS); -} - -/* - * CVodeGetIntegratorStats - * - * Returns integrator statistics - */ - -int CVodeGetIntegratorStats(void *cvode_mem, long int *nsteps, long int *nfevals, - long int *nlinsetups, long int *netfails, int *qlast, - int *qcur, realtype *hinused, realtype *hlast, - realtype *hcur, realtype *tcur) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetIntegratorStats", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *nsteps = nst; - *nfevals = nfe; - *nlinsetups = nsetups; - *netfails = netf; - *qlast = qu; - *qcur = next_q; - *hinused = h0u; - *hlast = hu; - *hcur = next_h; - *tcur = tn; - - return(CV_SUCCESS); -} - -/* - * CVodeGetNumGEvals - * - * Returns the current number of calls to g (for rootfinding) - */ - -int CVodeGetNumGEvals(void *cvode_mem, long int *ngevals) -{ - CVodeMem cv_mem; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetNumGEvals", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - *ngevals = nge; - - return(CV_SUCCESS); -} - -/* - * CVodeGetRootInfo - * - * Returns pointer to array rootsfound showing roots found - */ - -int CVodeGetRootInfo(void *cvode_mem, int *rootsfound) -{ - CVodeMem cv_mem; - int i, nrt; - - if (cvode_mem==NULL) { - CVProcessError(NULL, CV_MEM_NULL, "CVODE", "CVodeGetRootInfo", MSGCV_NO_MEM); - return(CV_MEM_NULL); - } - - cv_mem = (CVodeMem) cvode_mem; - - nrt = cv_mem->cv_nrtfn; - - for (i=0; i -#include - -#include "nvector_serial.h" -#include "sundials_math.h" - -#define ZERO RCONST(0.0) -#define HALF RCONST(0.5) -#define ONE RCONST(1.0) -#define ONEPT5 RCONST(1.5) - -/* Private function prototypes */ -/* z=x */ -static void VCopy_Serial(N_Vector x, N_Vector z); -/* z=x+y */ -static void VSum_Serial(N_Vector x, N_Vector y, N_Vector z); -/* z=x-y */ -static void VDiff_Serial(N_Vector x, N_Vector y, N_Vector z); -/* z=-x */ -static void VNeg_Serial(N_Vector x, N_Vector z); -/* z=c(x+y) */ -static void VScaleSum_Serial(realtype c, N_Vector x, N_Vector y, N_Vector z); -/* z=c(x-y) */ -static void VScaleDiff_Serial(realtype c, N_Vector x, N_Vector y, N_Vector z); -/* z=ax+y */ -static void VLin1_Serial(realtype a, N_Vector x, N_Vector y, N_Vector z); -/* z=ax-y */ -static void VLin2_Serial(realtype a, N_Vector x, N_Vector y, N_Vector z); -/* y <- ax+y */ -static void Vaxpy_Serial(realtype a, N_Vector x, N_Vector y); -/* x <- ax */ -static void VScaleBy_Serial(realtype a, N_Vector x); - -/* - * ----------------------------------------------------------------- - * exported functions - * ----------------------------------------------------------------- - */ - -/* ---------------------------------------------------------------------------- - * Function to create a new empty serial vector - */ - -N_Vector N_VNewEmpty_Serial(long int length) -{ - N_Vector v; - N_Vector_Ops ops; - N_VectorContent_Serial content; - - /* Create vector */ - v = NULL; - v = (N_Vector) malloc(sizeof *v); - if (v == NULL) return(NULL); - - /* Create vector operation structure */ - ops = NULL; - ops = (N_Vector_Ops) malloc(sizeof(struct _generic_N_Vector_Ops)); - if (ops == NULL) { free(v); return(NULL); } - - ops->nvclone = N_VClone_Serial; - ops->nvcloneempty = N_VCloneEmpty_Serial; - ops->nvdestroy = N_VDestroy_Serial; - ops->nvspace = N_VSpace_Serial; - ops->nvgetarraypointer = N_VGetArrayPointer_Serial; - ops->nvsetarraypointer = N_VSetArrayPointer_Serial; - ops->nvlinearsum = N_VLinearSum_Serial; - ops->nvconst = N_VConst_Serial; - ops->nvprod = N_VProd_Serial; - ops->nvdiv = N_VDiv_Serial; - ops->nvscale = N_VScale_Serial; - ops->nvabs = N_VAbs_Serial; - ops->nvinv = N_VInv_Serial; - ops->nvaddconst = N_VAddConst_Serial; - ops->nvdotprod = N_VDotProd_Serial; - ops->nvmaxnorm = N_VMaxNorm_Serial; - ops->nvwrmsnormmask = N_VWrmsNormMask_Serial; - ops->nvwrmsnorm = N_VWrmsNorm_Serial; - ops->nvmin = N_VMin_Serial; - ops->nvwl2norm = N_VWL2Norm_Serial; - ops->nvl1norm = N_VL1Norm_Serial; - ops->nvcompare = N_VCompare_Serial; - ops->nvinvtest = N_VInvTest_Serial; - ops->nvconstrmask = N_VConstrMask_Serial; - ops->nvminquotient = N_VMinQuotient_Serial; - - /* Create content */ - content = NULL; - content = (N_VectorContent_Serial) malloc(sizeof(struct _N_VectorContent_Serial)); - if (content == NULL) { free(ops); free(v); return(NULL); } - - content->length = length; - content->own_data = FALSE; - content->data = NULL; - - /* Attach content and ops */ - v->content = content; - v->ops = ops; - - return(v); -} - -/* ---------------------------------------------------------------------------- - * Function to create a new serial vector - */ - -N_Vector N_VNew_Serial(long int length) -{ - N_Vector v; - realtype *data; - - v = NULL; - v = N_VNewEmpty_Serial(length); - if (v == NULL) return(NULL); - - /* Create data */ - if (length > 0) { - - /* Allocate memory */ - data = NULL; - data = (realtype *) malloc(length * sizeof(realtype)); - if(data == NULL) { N_VDestroy_Serial(v); return(NULL); } - - /* Attach data */ - NV_OWN_DATA_S(v) = TRUE; - NV_DATA_S(v) = data; - - } - - return(v); -} - -/* ---------------------------------------------------------------------------- - * Function to create a serial N_Vector with user data component - */ - -N_Vector N_VMake_Serial(long int length, realtype *v_data) -{ - N_Vector v; - - v = NULL; - v = N_VNewEmpty_Serial(length); - if (v == NULL) return(NULL); - - if (length > 0) { - /* Attach data */ - NV_OWN_DATA_S(v) = FALSE; - NV_DATA_S(v) = v_data; - } - - return(v); -} - -/* ---------------------------------------------------------------------------- - * Function to create an array of new serial vectors. - */ - -N_Vector *N_VCloneVectorArray_Serial(int count, N_Vector w) -{ - N_Vector *vs; - int j; - - if (count <= 0) return(NULL); - - vs = NULL; - vs = (N_Vector *) malloc(count * sizeof(N_Vector)); - if(vs == NULL) return(NULL); - - for (j = 0; j < count; j++) { - vs[j] = NULL; - vs[j] = N_VClone_Serial(w); - if (vs[j] == NULL) { - N_VDestroyVectorArray_Serial(vs, j-1); - return(NULL); - } - } - - return(vs); -} - -/* ---------------------------------------------------------------------------- - * Function to create an array of new serial vectors with NULL data array. - */ - -N_Vector *N_VCloneVectorArrayEmpty_Serial(int count, N_Vector w) -{ - N_Vector *vs; - int j; - - if (count <= 0) return(NULL); - - vs = NULL; - vs = (N_Vector *) malloc(count * sizeof(N_Vector)); - if(vs == NULL) return(NULL); - - for (j = 0; j < count; j++) { - vs[j] = NULL; - vs[j] = N_VCloneEmpty_Serial(w); - if (vs[j] == NULL) { - N_VDestroyVectorArray_Serial(vs, j-1); - return(NULL); - } - } - - return(vs); -} - -/* ---------------------------------------------------------------------------- - * Function to free an array created with N_VCloneVectorArray_Serial - */ - -void N_VDestroyVectorArray_Serial(N_Vector *vs, int count) -{ - int j; - - for (j = 0; j < count; j++) N_VDestroy_Serial(vs[j]); - - free(vs); vs = NULL; - - return; -} - -/* ---------------------------------------------------------------------------- - * Function to print the a serial vector - */ - -void N_VPrint_Serial(N_Vector x) -{ - long int i, N; - realtype *xd; - - xd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - - for (i = 0; i < N; i++) { -#if defined(SUNDIALS_EXTENDED_PRECISION) - printf("%11.8Lg\n", xd[i]); -#elif defined(SUNDIALS_DOUBLE_PRECISION) - printf("%11.8lg\n", xd[i]); -#else - printf("%11.8g\n", xd[i]); -#endif - } - printf("\n"); - - return; -} - -/* - * ----------------------------------------------------------------- - * implementation of vector operations - * ----------------------------------------------------------------- - */ - -N_Vector N_VCloneEmpty_Serial(N_Vector w) -{ - N_Vector v; - N_Vector_Ops ops; - N_VectorContent_Serial content; - - if (w == NULL) return(NULL); - - /* Create vector */ - v = NULL; - v = (N_Vector) malloc(sizeof *v); - if (v == NULL) return(NULL); - - /* Create vector operation structure */ - ops = NULL; - ops = (N_Vector_Ops) malloc(sizeof(struct _generic_N_Vector_Ops)); - if (ops == NULL) { free(v); return(NULL); } - - ops->nvclone = w->ops->nvclone; - ops->nvcloneempty = w->ops->nvcloneempty; - ops->nvdestroy = w->ops->nvdestroy; - ops->nvspace = w->ops->nvspace; - ops->nvgetarraypointer = w->ops->nvgetarraypointer; - ops->nvsetarraypointer = w->ops->nvsetarraypointer; - ops->nvlinearsum = w->ops->nvlinearsum; - ops->nvconst = w->ops->nvconst; - ops->nvprod = w->ops->nvprod; - ops->nvdiv = w->ops->nvdiv; - ops->nvscale = w->ops->nvscale; - ops->nvabs = w->ops->nvabs; - ops->nvinv = w->ops->nvinv; - ops->nvaddconst = w->ops->nvaddconst; - ops->nvdotprod = w->ops->nvdotprod; - ops->nvmaxnorm = w->ops->nvmaxnorm; - ops->nvwrmsnormmask = w->ops->nvwrmsnormmask; - ops->nvwrmsnorm = w->ops->nvwrmsnorm; - ops->nvmin = w->ops->nvmin; - ops->nvwl2norm = w->ops->nvwl2norm; - ops->nvl1norm = w->ops->nvl1norm; - ops->nvcompare = w->ops->nvcompare; - ops->nvinvtest = w->ops->nvinvtest; - ops->nvconstrmask = w->ops->nvconstrmask; - ops->nvminquotient = w->ops->nvminquotient; - - /* Create content */ - content = NULL; - content = (N_VectorContent_Serial) malloc(sizeof(struct _N_VectorContent_Serial)); - if (content == NULL) { free(ops); free(v); return(NULL); } - - content->length = NV_LENGTH_S(w); - content->own_data = FALSE; - content->data = NULL; - - /* Attach content and ops */ - v->content = content; - v->ops = ops; - - return(v); -} - -N_Vector N_VClone_Serial(N_Vector w) -{ - N_Vector v; - realtype *data; - long int length; - - v = NULL; - v = N_VCloneEmpty_Serial(w); - if (v == NULL) return(NULL); - - length = NV_LENGTH_S(w); - - /* Create data */ - if (length > 0) { - - /* Allocate memory */ - data = NULL; - data = (realtype *) malloc(length * sizeof(realtype)); - if(data == NULL) { N_VDestroy_Serial(v); return(NULL); } - - /* Attach data */ - NV_OWN_DATA_S(v) = TRUE; - NV_DATA_S(v) = data; - - } - - return(v); -} - -void N_VDestroy_Serial(N_Vector v) -{ - if (NV_OWN_DATA_S(v) == TRUE) { - free(NV_DATA_S(v)); - NV_DATA_S(v) = NULL; - } - free(v->content); v->content = NULL; - free(v->ops); v->ops = NULL; - free(v); v = NULL; - - return; -} - -void N_VSpace_Serial(N_Vector v, long int *lrw, long int *liw) -{ - *lrw = NV_LENGTH_S(v); - *liw = 1; - - return; -} - -realtype *N_VGetArrayPointer_Serial(N_Vector v) -{ - return((realtype *) NV_DATA_S(v)); -} - -void N_VSetArrayPointer_Serial(realtype *v_data, N_Vector v) -{ - if (NV_LENGTH_S(v) > 0) NV_DATA_S(v) = v_data; - - return; -} - -void N_VLinearSum_Serial(realtype a, N_Vector x, realtype b, N_Vector y, N_Vector z) -{ - long int i, N; - realtype c, *xd, *yd, *zd; - N_Vector v1, v2; - booleantype test; - - xd = yd = zd = NULL; - - if ((b == ONE) && (z == y)) { /* BLAS usage: axpy y <- ax+y */ - Vaxpy_Serial(a,x,y); - return; - } - - if ((a == ONE) && (z == x)) { /* BLAS usage: axpy x <- by+x */ - Vaxpy_Serial(b,y,x); - return; - } - - /* Case: a == b == 1.0 */ - - if ((a == ONE) && (b == ONE)) { - VSum_Serial(x, y, z); - return; - } - - /* Cases: (1) a == 1.0, b = -1.0, (2) a == -1.0, b == 1.0 */ - - if ((test = ((a == ONE) && (b == -ONE))) || ((a == -ONE) && (b == ONE))) { - v1 = test ? y : x; - v2 = test ? x : y; - VDiff_Serial(v2, v1, z); - return; - } - - /* Cases: (1) a == 1.0, b == other or 0.0, (2) a == other or 0.0, b == 1.0 */ - /* if a or b is 0.0, then user should have called N_VScale */ - - if ((test = (a == ONE)) || (b == ONE)) { - c = test ? b : a; - v1 = test ? y : x; - v2 = test ? x : y; - VLin1_Serial(c, v1, v2, z); - return; - } - - /* Cases: (1) a == -1.0, b != 1.0, (2) a != 1.0, b == -1.0 */ - - if ((test = (a == -ONE)) || (b == -ONE)) { - c = test ? b : a; - v1 = test ? y : x; - v2 = test ? x : y; - VLin2_Serial(c, v1, v2, z); - return; - } - - /* Case: a == b */ - /* catches case both a and b are 0.0 - user should have called N_VConst */ - - if (a == b) { - VScaleSum_Serial(a, x, y, z); - return; - } - - /* Case: a == -b */ - - if (a == -b) { - VScaleDiff_Serial(a, x, y, z); - return; - } - - /* Do all cases not handled above: - (1) a == other, b == 0.0 - user should have called N_VScale - (2) a == 0.0, b == other - user should have called N_VScale - (3) a,b == other, a !=b, a != -b */ - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - yd = NV_DATA_S(y); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = (a*xd[i])+(b*yd[i]); - - return; -} - -void N_VConst_Serial(realtype c, N_Vector z) -{ - long int i, N; - realtype *zd; - - zd = NULL; - - N = NV_LENGTH_S(z); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) zd[i] = c; - - return; -} - -void N_VProd_Serial(N_Vector x, N_Vector y, N_Vector z) -{ - long int i, N; - realtype *xd, *yd, *zd; - - xd = yd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - yd = NV_DATA_S(y); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = xd[i]*yd[i]; - - return; -} - -void N_VDiv_Serial(N_Vector x, N_Vector y, N_Vector z) -{ - long int i, N; - realtype *xd, *yd, *zd; - - xd = yd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - yd = NV_DATA_S(y); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = xd[i]/yd[i]; - - return; -} - -void N_VScale_Serial(realtype c, N_Vector x, N_Vector z) -{ - long int i, N; - realtype *xd, *zd; - - xd = zd = NULL; - - if (z == x) { /* BLAS usage: scale x <- cx */ - VScaleBy_Serial(c, x); - return; - } - - if (c == ONE) { - VCopy_Serial(x, z); - } else if (c == -ONE) { - VNeg_Serial(x, z); - } else { - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - zd = NV_DATA_S(z); - for (i = 0; i < N; i++) - zd[i] = c*xd[i]; - } - - return; -} - -void N_VAbs_Serial(N_Vector x, N_Vector z) -{ - long int i, N; - realtype *xd, *zd; - - xd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = ABS(xd[i]); - - return; -} - -void N_VInv_Serial(N_Vector x, N_Vector z) -{ - long int i, N; - realtype *xd, *zd; - - xd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = ONE/xd[i]; - - return; -} - -void N_VAddConst_Serial(N_Vector x, realtype b, N_Vector z) -{ - long int i, N; - realtype *xd, *zd; - - xd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = xd[i]+b; - - return; -} - -realtype N_VDotProd_Serial(N_Vector x, N_Vector y) -{ - long int i, N; - realtype sum, *xd, *yd; - - sum = ZERO; - xd = yd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - yd = NV_DATA_S(y); - - for (i = 0; i < N; i++) - sum += xd[i]*yd[i]; - - return(sum); -} - -realtype N_VMaxNorm_Serial(N_Vector x) -{ - long int i, N; - realtype max, *xd; - - max = ZERO; - xd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - - for (i = 0; i < N; i++) { - if (ABS(xd[i]) > max) max = ABS(xd[i]); - } - - return(max); -} - -realtype N_VWrmsNorm_Serial(N_Vector x, N_Vector w) -{ - long int i, N; - realtype sum, prodi, *xd, *wd; - - sum = ZERO; - xd = wd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - wd = NV_DATA_S(w); - - for (i = 0; i < N; i++) { - prodi = xd[i]*wd[i]; - sum += SQR(prodi); - } - - return(RSqrt(sum/N)); -} - -realtype N_VWrmsNormMask_Serial(N_Vector x, N_Vector w, N_Vector id) -{ - long int i, N; - realtype sum, prodi, *xd, *wd, *idd; - - sum = ZERO; - xd = wd = idd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - wd = NV_DATA_S(w); - idd = NV_DATA_S(id); - - for (i = 0; i < N; i++) { - if (idd[i] > ZERO) { - prodi = xd[i]*wd[i]; - sum += SQR(prodi); - } - } - - return(RSqrt(sum / N)); -} - -realtype N_VMin_Serial(N_Vector x) -{ - long int i, N; - realtype min, *xd; - - xd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - - min = xd[0]; - - for (i = 1; i < N; i++) { - if (xd[i] < min) min = xd[i]; - } - - return(min); -} - -realtype N_VWL2Norm_Serial(N_Vector x, N_Vector w) -{ - long int i, N; - realtype sum, prodi, *xd, *wd; - - sum = ZERO; - xd = wd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - wd = NV_DATA_S(w); - - for (i = 0; i < N; i++) { - prodi = xd[i]*wd[i]; - sum += SQR(prodi); - } - - return(RSqrt(sum)); -} - -realtype N_VL1Norm_Serial(N_Vector x) -{ - long int i, N; - realtype sum, *xd; - - sum = ZERO; - xd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - - for (i = 0; i= c) ? ONE : ZERO; - } - - return; -} - -booleantype N_VInvTest_Serial(N_Vector x, N_Vector z) -{ - long int i, N; - realtype *xd, *zd; - - xd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) { - if (xd[i] == ZERO) return(FALSE); - zd[i] = ONE/xd[i]; - } - - return(TRUE); -} - -booleantype N_VConstrMask_Serial(N_Vector c, N_Vector x, N_Vector m) -{ - long int i, N; - booleantype test; - realtype *cd, *xd, *md; - - cd = xd = md = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - cd = NV_DATA_S(c); - md = NV_DATA_S(m); - - test = TRUE; - - for (i = 0; i < N; i++) { - md[i] = ZERO; - if (cd[i] == ZERO) continue; - if (cd[i] > ONEPT5 || cd[i] < -ONEPT5) { - if ( xd[i]*cd[i] <= ZERO) { test = FALSE; md[i] = ONE; } - continue; - } - if ( cd[i] > HALF || cd[i] < -HALF) { - if (xd[i]*cd[i] < ZERO ) { test = FALSE; md[i] = ONE; } - } - } - - return(test); -} - -realtype N_VMinQuotient_Serial(N_Vector num, N_Vector denom) -{ - booleantype notEvenOnce; - long int i, N; - realtype *nd, *dd, min; - - nd = dd = NULL; - - N = NV_LENGTH_S(num); - nd = NV_DATA_S(num); - dd = NV_DATA_S(denom); - - notEvenOnce = TRUE; - min = BIG_REAL; - - for (i = 0; i < N; i++) { - if (dd[i] == ZERO) continue; - else { - if (!notEvenOnce) min = MIN(min, nd[i]/dd[i]); - else { - min = nd[i]/dd[i]; - notEvenOnce = FALSE; - } - } - } - - return(min); -} - -/* - * ----------------------------------------------------------------- - * private functions - * ----------------------------------------------------------------- - */ - -static void VCopy_Serial(N_Vector x, N_Vector z) -{ - long int i, N; - realtype *xd, *zd; - - xd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = xd[i]; - - return; -} - -static void VSum_Serial(N_Vector x, N_Vector y, N_Vector z) -{ - long int i, N; - realtype *xd, *yd, *zd; - - xd = yd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - yd = NV_DATA_S(y); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = xd[i]+yd[i]; - - return; -} - -static void VDiff_Serial(N_Vector x, N_Vector y, N_Vector z) -{ - long int i, N; - realtype *xd, *yd, *zd; - - xd = yd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - yd = NV_DATA_S(y); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = xd[i]-yd[i]; - - return; -} - -static void VNeg_Serial(N_Vector x, N_Vector z) -{ - long int i, N; - realtype *xd, *zd; - - xd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = -xd[i]; - - return; -} - -static void VScaleSum_Serial(realtype c, N_Vector x, N_Vector y, N_Vector z) -{ - long int i, N; - realtype *xd, *yd, *zd; - - xd = yd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - yd = NV_DATA_S(y); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = c*(xd[i]+yd[i]); - - return; -} - -static void VScaleDiff_Serial(realtype c, N_Vector x, N_Vector y, N_Vector z) -{ - long int i, N; - realtype *xd, *yd, *zd; - - xd = yd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - yd = NV_DATA_S(y); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = c*(xd[i]-yd[i]); - - return; -} - -static void VLin1_Serial(realtype a, N_Vector x, N_Vector y, N_Vector z) -{ - long int i, N; - realtype *xd, *yd, *zd; - - xd = yd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - yd = NV_DATA_S(y); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = (a*xd[i])+yd[i]; - - return; -} - -static void VLin2_Serial(realtype a, N_Vector x, N_Vector y, N_Vector z) -{ - long int i, N; - realtype *xd, *yd, *zd; - - xd = yd = zd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - yd = NV_DATA_S(y); - zd = NV_DATA_S(z); - - for (i = 0; i < N; i++) - zd[i] = (a*xd[i])-yd[i]; - - return; -} - -static void Vaxpy_Serial(realtype a, N_Vector x, N_Vector y) -{ - long int i, N; - realtype *xd, *yd; - - xd = yd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - yd = NV_DATA_S(y); - - if (a == ONE) { - for (i = 0; i < N; i++) - yd[i] += xd[i]; - return; - } - - if (a == -ONE) { - for (i = 0; i < N; i++) - yd[i] -= xd[i]; - return; - } - - for (i = 0; i < N; i++) - yd[i] += a*xd[i]; - - return; -} - -static void VScaleBy_Serial(realtype a, N_Vector x) -{ - long int i, N; - realtype *xd; - - xd = NULL; - - N = NV_LENGTH_S(x); - xd = NV_DATA_S(x); - - for (i = 0; i < N; i++) - xd[i] *= a; - - return; -} diff --git a/src/amuse/community/secularmultiple/src/cvode/nvector_serial.h b/src/amuse/community/secularmultiple/src/cvode/nvector_serial.h deleted file mode 100755 index 7782ec9541..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/nvector_serial.h +++ /dev/null @@ -1,265 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.2 $ - * $Date: 2006/11/29 00:05:07 $ - * ----------------------------------------------------------------- - * Programmer(s): Scott D. Cohen, Alan C. Hindmarsh, Radu Serban, - * and Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the header file for the serial implementation of the - * NVECTOR module. - * - * Part I contains declarations specific to the serial - * implementation of the supplied NVECTOR module. - * - * Part II defines accessor macros that allow the user to - * efficiently use the type N_Vector without making explicit - * references to the underlying data structure. - * - * Part III contains the prototype for the constructor N_VNew_Serial - * as well as implementation-specific prototypes for various useful - * vector operations. - * - * Notes: - * - * - The definition of the generic N_Vector structure can be found - * in the header file sundials_nvector.h. - * - * - The definition of the type 'realtype' can be found in the - * header file sundials_types.h, and it may be changed (at the - * configuration stage) according to the user's needs. - * The sundials_types.h file also contains the definition - * for the type 'booleantype'. - * - * - N_Vector arguments to arithmetic vector operations need not - * be distinct. For example, the following call: - * - * N_VLinearSum_Serial(a,x,b,y,y); - * - * (which stores the result of the operation a*x+b*y in y) - * is legal. - * ----------------------------------------------------------------- - */ - -#ifndef _NVECTOR_SERIAL_H -#define _NVECTOR_SERIAL_H - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -#include "sundials_nvector.h" - -/* - * ----------------------------------------------------------------- - * PART I: SERIAL implementation of N_Vector - * ----------------------------------------------------------------- - */ - -/* serial implementation of the N_Vector 'content' structure - contains the length of the vector, a pointer to an array - of 'realtype' components, and a flag indicating ownership of - the data */ - -struct _N_VectorContent_Serial { - long int length; - booleantype own_data; - realtype *data; -}; - -typedef struct _N_VectorContent_Serial *N_VectorContent_Serial; - -/* - * ----------------------------------------------------------------- - * PART II: macros NV_CONTENT_S, NV_DATA_S, NV_OWN_DATA_S, - * NV_LENGTH_S, and NV_Ith_S - * ----------------------------------------------------------------- - * In the descriptions below, the following user declarations - * are assumed: - * - * N_Vector v; - * long int i; - * - * (1) NV_CONTENT_S - * - * This routines gives access to the contents of the serial - * vector N_Vector. - * - * The assignment v_cont = NV_CONTENT_S(v) sets v_cont to be - * a pointer to the serial N_Vector content structure. - * - * (2) NV_DATA_S NV_OWN_DATA_S and NV_LENGTH_S - * - * These routines give access to the individual parts of - * the content structure of a serial N_Vector. - * - * The assignment v_data = NV_DATA_S(v) sets v_data to be - * a pointer to the first component of v. The assignment - * NV_DATA_S(v) = data_V sets the component array of v to - * be data_v by storing the pointer data_v. - * - * The assignment v_len = NV_LENGTH_S(v) sets v_len to be - * the length of v. The call NV_LENGTH_S(v) = len_v sets - * the length of v to be len_v. - * - * (3) NV_Ith_S - * - * In the following description, the components of an - * N_Vector are numbered 0..n-1, where n is the length of v. - * - * The assignment r = NV_Ith_S(v,i) sets r to be the value of - * the ith component of v. The assignment NV_Ith_S(v,i) = r - * sets the value of the ith component of v to be r. - * - * Note: When looping over the components of an N_Vector v, it is - * more efficient to first obtain the component array via - * v_data = NV_DATA_S(v) and then access v_data[i] within the - * loop than it is to use NV_Ith_S(v,i) within the loop. - * ----------------------------------------------------------------- - */ - -#define NV_CONTENT_S(v) ( (N_VectorContent_Serial)(v->content) ) - -#define NV_LENGTH_S(v) ( NV_CONTENT_S(v)->length ) - -#define NV_OWN_DATA_S(v) ( NV_CONTENT_S(v)->own_data ) - -#define NV_DATA_S(v) ( NV_CONTENT_S(v)->data ) - -#define NV_Ith_S(v,i) ( NV_DATA_S(v)[i] ) - -/* - * ----------------------------------------------------------------- - * PART III: functions exported by nvector_serial - * - * CONSTRUCTORS: - * N_VNew_Serial - * N_VNewEmpty_Serial - * N_VMake_Serial - * N_VCloneVectorArray_Serial - * N_VCloneVectorArrayEmpty_Serial - * DESTRUCTORS: - * N_VDestroy_Serial - * N_VDestroyVectorArray_Serial - * OTHER: - * N_VPrint_Serial - * ----------------------------------------------------------------- - */ - -/* - * ----------------------------------------------------------------- - * Function : N_VNew_Serial - * ----------------------------------------------------------------- - * This function creates and allocates memory for a serial vector. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT N_Vector N_VNew_Serial(long int vec_length); - -/* - * ----------------------------------------------------------------- - * Function : N_VNewEmpty_Serial - * ----------------------------------------------------------------- - * This function creates a new serial N_Vector with an empty (NULL) - * data array. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT N_Vector N_VNewEmpty_Serial(long int vec_length); - -/* - * ----------------------------------------------------------------- - * Function : N_VMake_Serial - * ----------------------------------------------------------------- - * This function creates and allocates memory for a serial vector - * with a user-supplied data array. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT N_Vector N_VMake_Serial(long int vec_length, realtype *v_data); - -/* - * ----------------------------------------------------------------- - * Function : N_VCloneVectorArray_Serial - * ----------------------------------------------------------------- - * This function creates an array of 'count' SERIAL vectors by - * cloning a given vector w. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT N_Vector *N_VCloneVectorArray_Serial(int count, N_Vector w); - -/* - * ----------------------------------------------------------------- - * Function : N_VCloneVectorArrayEmpty_Serial - * ----------------------------------------------------------------- - * This function creates an array of 'count' SERIAL vectors each - * with an empty (NULL) data array by cloning w. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT N_Vector *N_VCloneVectorArrayEmpty_Serial(int count, N_Vector w); - -/* - * ----------------------------------------------------------------- - * Function : N_VDestroyVectorArray_Serial - * ----------------------------------------------------------------- - * This function frees an array of SERIAL vectors created with - * N_VCloneVectorArray_Serial or N_VCloneVectorArrayEmpty_Serial. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void N_VDestroyVectorArray_Serial(N_Vector *vs, int count); - -/* - * ----------------------------------------------------------------- - * Function : N_VPrint_Serial - * ----------------------------------------------------------------- - * This function prints the content of a serial vector to stdout. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void N_VPrint_Serial(N_Vector v); - -/* - * ----------------------------------------------------------------- - * serial implementations of various useful vector operations - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT N_Vector N_VCloneEmpty_Serial(N_Vector w); -SUNDIALS_EXPORT N_Vector N_VClone_Serial(N_Vector w); -SUNDIALS_EXPORT void N_VDestroy_Serial(N_Vector v); -SUNDIALS_EXPORT void N_VSpace_Serial(N_Vector v, long int *lrw, long int *liw); -SUNDIALS_EXPORT realtype *N_VGetArrayPointer_Serial(N_Vector v); -SUNDIALS_EXPORT void N_VSetArrayPointer_Serial(realtype *v_data, N_Vector v); -SUNDIALS_EXPORT void N_VLinearSum_Serial(realtype a, N_Vector x, realtype b, N_Vector y, N_Vector z); -SUNDIALS_EXPORT void N_VConst_Serial(realtype c, N_Vector z); -SUNDIALS_EXPORT void N_VProd_Serial(N_Vector x, N_Vector y, N_Vector z); -SUNDIALS_EXPORT void N_VDiv_Serial(N_Vector x, N_Vector y, N_Vector z); -SUNDIALS_EXPORT void N_VScale_Serial(realtype c, N_Vector x, N_Vector z); -SUNDIALS_EXPORT void N_VAbs_Serial(N_Vector x, N_Vector z); -SUNDIALS_EXPORT void N_VInv_Serial(N_Vector x, N_Vector z); -SUNDIALS_EXPORT void N_VAddConst_Serial(N_Vector x, realtype b, N_Vector z); -SUNDIALS_EXPORT realtype N_VDotProd_Serial(N_Vector x, N_Vector y); -SUNDIALS_EXPORT realtype N_VMaxNorm_Serial(N_Vector x); -SUNDIALS_EXPORT realtype N_VWrmsNorm_Serial(N_Vector x, N_Vector w); -SUNDIALS_EXPORT realtype N_VWrmsNormMask_Serial(N_Vector x, N_Vector w, N_Vector id); -SUNDIALS_EXPORT realtype N_VMin_Serial(N_Vector x); -SUNDIALS_EXPORT realtype N_VWL2Norm_Serial(N_Vector x, N_Vector w); -SUNDIALS_EXPORT realtype N_VL1Norm_Serial(N_Vector x); -SUNDIALS_EXPORT void N_VCompare_Serial(realtype c, N_Vector x, N_Vector z); -SUNDIALS_EXPORT booleantype N_VInvTest_Serial(N_Vector x, N_Vector z); -SUNDIALS_EXPORT booleantype N_VConstrMask_Serial(N_Vector c, N_Vector x, N_Vector m); -SUNDIALS_EXPORT realtype N_VMinQuotient_Serial(N_Vector num, N_Vector denom); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/amuse/community/secularmultiple/src/cvode/sundials_config.h b/src/amuse/community/secularmultiple/src/cvode/sundials_config.h deleted file mode 100755 index 3623a45c04..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/sundials_config.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.4 $ - * $Date: 2007/12/19 20:34:00 $ - * ----------------------------------------------------------------- - * Programmer(s): Aaron Collier and Radu Serban @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2005, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - *------------------------------------------------------------------ - * SUNDIALS configuration header file - *------------------------------------------------------------------ - */ - -/* Define SUNDIALS version number */ -#define SUNDIALS_PACKAGE_VERSION "2.4.0" - -/* FCMIX: Define Fortran name-mangling macro for C identifiers. - * Depending on the inferred scheme, one of the following six - * macros will be defined: - * #define SUNDIALS_F77_FUNC(name,NAME) name - * #define SUNDIALS_F77_FUNC(name,NAME) name ## _ - * #define SUNDIALS_F77_FUNC(name,NAME) name ## __ - * #define SUNDIALS_F77_FUNC(name,NAME) NAME - * #define SUNDIALS_F77_FUNC(name,NAME) NAME ## _ - * #define SUNDIALS_F77_FUNC(name,NAME) NAME ## __ - */ - - -/* FCMIX: Define Fortran name-mangling macro for C identifiers - * which contain underscores. - */ - - -/* Define precision of SUNDIALS data type 'realtype' - * Depending on the precision level, one of the following - * three macros will be defined: - * #define SUNDIALS_SINGLE_PRECISION 1 - * #define SUNDIALS_DOUBLE_PRECISION 1 - * #define SUNDIALS_EXTENDED_PRECISION 1 - */ -#define SUNDIALS_DOUBLE_PRECISION 1 - -/* Use generic math functions - * If it was decided that generic math functions can be used, then - * #define SUNDIALS_USE_GENERIC_MATH 1 - * otherwise - * #define SUNDIALS_USE_GENERIC_MATH 0 - */ -#define SUNDIALS_USE_GENERIC_MATH 1 - -/* Blas/Lapack available - * If working libraries for Blas/lapack support were found, then - * #define SUNDIALS_BLAS_LAPACK 1 - * otherwise - * #define SUNDIALS_BLAS_LAPACK 0 - */ -#define SUNDIALS_BLAS_LAPACK 0 - -/* FNVECTOR: Allow user to specify different MPI communicator - * If it was found that the MPI implementation supports MPI_Comm_f2c, then - * #define SUNDIALS_MPI_COMM_F2C 1 - * otherwise - * #define SUNDIALS_MPI_COMM_F2C 0 - */ - - -/* Mark SUNDIALS API functions for export/import - * When building shared SUNDIALS libraries under Windows, use - * #define SUNDIALS_EXPORT __declspec(dllexport) - * When linking to shared SUNDIALS libraries under Windows, use - * #define SUNDIALS_EXPORT __declspec(dllimport) - * In all other cases (other platforms or static libraries under - * Windows), the SUNDIALS_EXPORT macro is empty - */ -#define SUNDIALS_EXPORT diff --git a/src/amuse/community/secularmultiple/src/cvode/sundials_dense.c b/src/amuse/community/secularmultiple/src/cvode/sundials_dense.c deleted file mode 100755 index ffa84a15c3..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/sundials_dense.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.6 $ - * $Date: 2009/02/17 02:42:29 $ - * ----------------------------------------------------------------- - * Programmer(s): Scott D. Cohen, Alan C. Hindmarsh and - * Radu Serban @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the implementation file for a generic package of dense - * matrix operations. - * ----------------------------------------------------------------- - */ - -#include -#include - -#include "sundials_dense.h" -#include "sundials_math.h" - -#define ZERO RCONST(0.0) -#define ONE RCONST(1.0) -#define TWO RCONST(2.0) - -/* - * ----------------------------------------------------- - * Functions working on DlsMat - * ----------------------------------------------------- - */ - -int DenseGETRF(DlsMat A, int *p) -{ - return(denseGETRF(A->cols, A->M, A->N, p)); -} - -void DenseGETRS(DlsMat A, int *p, realtype *b) -{ - denseGETRS(A->cols, A->N, p, b); -} - -int DensePOTRF(DlsMat A) -{ - return(densePOTRF(A->cols, A->M)); -} - -void DensePOTRS(DlsMat A, realtype *b) -{ - densePOTRS(A->cols, A->M, b); -} - -int DenseGEQRF(DlsMat A, realtype *beta, realtype *wrk) -{ - return(denseGEQRF(A->cols, A->M, A->N, beta, wrk)); -} - -int DenseORMQR(DlsMat A, realtype *beta, realtype *vn, realtype *vm, realtype *wrk) -{ - return(denseORMQR(A->cols, A->M, A->N, beta, vn, vm, wrk)); -} - -void DenseCopy(DlsMat A, DlsMat B) -{ - denseCopy(A->cols, B->cols, A->M, A->N); -} - -void DenseScale(realtype c, DlsMat A) -{ - denseScale(c, A->cols, A->M, A->N); -} - -int denseGETRF(realtype **a, int m, int n, int *p) -{ - int i, j, k, l; - realtype *col_j, *col_k; - realtype temp, mult, a_kj; - - /* k-th elimination step number */ - for (k=0; k < n; k++) { - - col_k = a[k]; - - /* find l = pivot row number */ - l=k; - for (i=k+1; i < m; i++) - if (ABS(col_k[i]) > ABS(col_k[l])) l=i; - p[k] = l; - - /* check for zero pivot element */ - if (col_k[l] == ZERO) return(k+1); - - /* swap a(k,1:n) and a(l,1:n) if necessary */ - if ( l!= k ) { - for (i=0; i 0; k--) { - col_k = a[k]; - b[k] /= col_k[k]; - for (i=0; i0) { - for(i=j; i=0; i--) { - col_i = a[i]; - for (j=i+1; j= n) - * using Householder reflections. - * - * On exit, the elements on and above the diagonal of A contain the n by n - * upper triangular matrix R; the elements below the diagonal, with the array beta, - * represent the orthogonal matrix Q as a product of elementary reflectors . - * - * v (of length m) must be provided as workspace. - * - */ - -int denseGEQRF(realtype **a, int m, int n, realtype *beta, realtype *v) -{ - realtype ajj, s, mu, v1, v1_2; - realtype *col_j, *col_k; - int i, j, k; - - /* For each column...*/ - for(j=0; j= n. - * - * v (of length m) must be provided as workspace. - */ -int denseORMQR(realtype **a, int m, int n, realtype *beta, - realtype *vn, realtype *vm, realtype *v) -{ - realtype *col_j, s; - int i, j; - - /* Initialize vm */ - for(i=0; i=0; j--) { - - col_j = a[j]; - - v[0] = ONE; - s = vm[j]; - for(i=1; i= N and full column rank. - * - * A successful LU factorization leaves the matrix A and the - * pivot array p with the following information: - * - * (1) p[k] contains the row number of the pivot element chosen - * at the beginning of elimination step k, k=0, 1, ..., N-1. - * - * (2) If the unique LU factorization of A is given by PA = LU, - * where P is a permutation matrix, L is a lower trapezoidal - * matrix with all 1's on the diagonal, and U is an upper - * triangular matrix, then the upper triangular part of A - * (including its diagonal) contains U and the strictly lower - * trapezoidal part of A contains the multipliers, I-L. - * - * For square matrices (M=N), L is unit lower triangular. - * - * DenseGETRF returns 0 if successful. Otherwise it encountered - * a zero diagonal element during the factorization. In this case - * it returns the column index (numbered from one) at which - * it encountered the zero. - * - * DenseGETRS solves the N-dimensional system A x = b using - * the LU factorization in A and the pivot information in p - * computed in DenseGETRF. The solution x is returned in b. This - * routine cannot fail if the corresponding call to DenseGETRF - * did not fail. - * DenseGETRS does NOT check for a square matrix! - * - * ----------------------------------------------------------------- - * DenseGETRF and DenseGETRS are simply wrappers around denseGETRF - * and denseGETRS, respectively, which perform all the work by - * directly accessing the data in the DlsMat A (i.e. the field cols) - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int DenseGETRF(DlsMat A, int *p); -SUNDIALS_EXPORT void DenseGETRS(DlsMat A, int *p, realtype *b); - -SUNDIALS_EXPORT int denseGETRF(realtype **a, int m, int n, int *p); -SUNDIALS_EXPORT void denseGETRS(realtype **a, int n, int *p, realtype *b); - -/* - * ----------------------------------------------------------------- - * Functions : DensePOTRF and DensePOTRS - * ----------------------------------------------------------------- - * DensePOTRF computes the Cholesky factorization of a real symmetric - * positive definite matrix A. - * ----------------------------------------------------------------- - * DensePOTRS solves a system of linear equations A*X = B with a - * symmetric positive definite matrix A using the Cholesky factorization - * A = L*L**T computed by DensePOTRF. - * - * ----------------------------------------------------------------- - * DensePOTRF and DensePOTRS are simply wrappers around densePOTRF - * and densePOTRS, respectively, which perform all the work by - * directly accessing the data in the DlsMat A (i.e. the field cols) - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int DensePOTRF(DlsMat A); -SUNDIALS_EXPORT void DensePOTRS(DlsMat A, realtype *b); - -SUNDIALS_EXPORT int densePOTRF(realtype **a, int m); -SUNDIALS_EXPORT void densePOTRS(realtype **a, int m, realtype *b); - -/* - * ----------------------------------------------------------------- - * Functions : DenseGEQRF and DenseORMQR - * ----------------------------------------------------------------- - * DenseGEQRF computes a QR factorization of a real M-by-N matrix A: - * A = Q * R (with M>= N). - * - * DenseGEQRF requires a temporary work vector wrk of length M. - * ----------------------------------------------------------------- - * DenseORMQR computes the product w = Q * v where Q is a real - * orthogonal matrix defined as the product of k elementary reflectors - * - * Q = H(1) H(2) . . . H(k) - * - * as returned by DenseGEQRF. Q is an M-by-N matrix, v is a vector - * of length N and w is a vector of length M (with M>=N). - * - * DenseORMQR requires a temporary work vector wrk of length M. - * - * ----------------------------------------------------------------- - * DenseGEQRF and DenseORMQR are simply wrappers around denseGEQRF - * and denseORMQR, respectively, which perform all the work by - * directly accessing the data in the DlsMat A (i.e. the field cols) - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int DenseGEQRF(DlsMat A, realtype *beta, realtype *wrk); -SUNDIALS_EXPORT int DenseORMQR(DlsMat A, realtype *beta, realtype *vn, realtype *vm, - realtype *wrk); - -SUNDIALS_EXPORT int denseGEQRF(realtype **a, int m, int n, realtype *beta, realtype *v); -SUNDIALS_EXPORT int denseORMQR(realtype **a, int m, int n, realtype *beta, - realtype *v, realtype *w, realtype *wrk); - -/* - * ----------------------------------------------------------------- - * Function : DenseCopy - * ----------------------------------------------------------------- - * DenseCopy copies the contents of the M-by-N matrix A into the - * M-by-N matrix B. - * - * DenseCopy is a wrapper around denseCopy which accesses the data - * in the DlsMat A and B (i.e. the fields cols) - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void DenseCopy(DlsMat A, DlsMat B); -SUNDIALS_EXPORT void denseCopy(realtype **a, realtype **b, int m, int n); - -/* - * ----------------------------------------------------------------- - * Function: DenseScale - * ----------------------------------------------------------------- - * DenseScale scales the elements of the M-by-N matrix A by the - * constant c and stores the result back in A. - * - * DenseScale is a wrapper around denseScale which performs the actual - * scaling by accessing the data in the DlsMat A (i.e. the field - * cols). - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void DenseScale(realtype c, DlsMat A); -SUNDIALS_EXPORT void denseScale(realtype c, realtype **a, int m, int n); - - -/* - * ----------------------------------------------------------------- - * Function: denseAddIdentity - * ----------------------------------------------------------------- - * denseAddIdentity adds the identity matrix to the n-by-n matrix - * stored in the realtype** arrays. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void denseAddIdentity(realtype **a, int n); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/amuse/community/secularmultiple/src/cvode/sundials_direct.c b/src/amuse/community/secularmultiple/src/cvode/sundials_direct.c deleted file mode 100755 index 0bb9d6dcbf..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/sundials_direct.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.3 $ - * $Date: 2009/02/17 02:42:29 $ - * ----------------------------------------------------------------- - * Programmer: Radu Serban @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the implementation file for operations to be used by a - * generic direct linear solver. - * ----------------------------------------------------------------- - */ - -#include -#include - -#include "sundials_direct.h" -#include "sundials_math.h" - -#define ZERO RCONST(0.0) -#define ONE RCONST(1.0) - -DlsMat NewDenseMat(int M, int N) -{ - DlsMat A; - int j; - - if ( (M <= 0) || (N <= 0) ) return(NULL); - - A = NULL; - A = (DlsMat) malloc(sizeof *A); - if (A==NULL) return (NULL); - - A->data = (realtype *) malloc(M * N * sizeof(realtype)); - if (A->data == NULL) { - free(A); A = NULL; - return(NULL); - } - A->cols = (realtype **) malloc(N * sizeof(realtype *)); - if (A->cols == NULL) { - free(A->data); A->data = NULL; - free(A); A = NULL; - return(NULL); - } - - for (j=0; j < N; j++) A->cols[j] = A->data + j * M; - - A->M = M; - A->N = N; - A->ldim = M; - A->ldata = M*N; - - A->type = SUNDIALS_DENSE; - - return(A); -} - -realtype **newDenseMat(int m, int n) -{ - int j; - realtype **a; - - if ( (n <= 0) || (m <= 0) ) return(NULL); - - a = NULL; - a = (realtype **) malloc(n * sizeof(realtype *)); - if (a == NULL) return(NULL); - - a[0] = NULL; - a[0] = (realtype *) malloc(m * n * sizeof(realtype)); - if (a[0] == NULL) { - free(a); a = NULL; - return(NULL); - } - - for (j=1; j < n; j++) a[j] = a[0] + j * m; - - return(a); -} - - -DlsMat NewBandMat(int N, int mu, int ml, int smu) -{ - DlsMat A; - int j, colSize; - - if (N <= 0) return(NULL); - - A = NULL; - A = (DlsMat) malloc(sizeof *A); - if (A == NULL) return (NULL); - - colSize = smu + ml + 1; - A->data = NULL; - A->data = (realtype *) malloc(N * colSize * sizeof(realtype)); - if (A->data == NULL) { - free(A); A = NULL; - return(NULL); - } - - A->cols = NULL; - A->cols = (realtype **) malloc(N * sizeof(realtype *)); - if (A->cols == NULL) { - free(A->data); - free(A); A = NULL; - return(NULL); - } - - for (j=0; j < N; j++) A->cols[j] = A->data + j * colSize; - - A->M = N; - A->N = N; - A->mu = mu; - A->ml = ml; - A->s_mu = smu; - A->ldim = colSize; - A->ldata = N * colSize; - - A->type = SUNDIALS_BAND; - - return(A); -} - -realtype **newBandMat(int n, int smu, int ml) -{ - realtype **a; - int j, colSize; - - if (n <= 0) return(NULL); - - a = NULL; - a = (realtype **) malloc(n * sizeof(realtype *)); - if (a == NULL) return(NULL); - - colSize = smu + ml + 1; - a[0] = NULL; - a[0] = (realtype *) malloc(n * colSize * sizeof(realtype)); - if (a[0] == NULL) { - free(a); a = NULL; - return(NULL); - } - - for (j=1; j < n; j++) a[j] = a[0] + j * colSize; - - return(a); -} - -void DestroyMat(DlsMat A) -{ - free(A->data); A->data = NULL; - free(A->cols); - free(A); A = NULL; -} - -void destroyMat(realtype **a) -{ - free(a[0]); a[0] = NULL; - free(a); a = NULL; -} - -int *NewIntArray(int N) -{ - int *vec; - - if (N <= 0) return(NULL); - - vec = NULL; - vec = (int *) malloc(N * sizeof(int)); - - return(vec); -} - -int *newIntArray(int n) -{ - int *v; - - if (n <= 0) return(NULL); - - v = NULL; - v = (int *) malloc(n * sizeof(int)); - - return(v); -} - -realtype *NewRealArray(int N) -{ - realtype *vec; - - if (N <= 0) return(NULL); - - vec = NULL; - vec = (realtype *) malloc(N * sizeof(realtype)); - - return(vec); -} - -realtype *newRealArray(int m) -{ - realtype *v; - - if (m <= 0) return(NULL); - - v = NULL; - v = (realtype *) malloc(m * sizeof(realtype)); - - return(v); -} - -void DestroyArray(void *V) -{ - free(V); - V = NULL; -} - -void destroyArray(void *v) -{ - free(v); - v = NULL; -} - - -void AddIdentity(DlsMat A) -{ - int i; - - switch (A->type) { - - case SUNDIALS_DENSE: - for (i=0; iN; i++) A->cols[i][i] += ONE; - break; - - case SUNDIALS_BAND: - for (i=0; iM; i++) A->cols[i][A->s_mu] += ONE; - break; - - } - -} - - -void SetToZero(DlsMat A) -{ - int i, j, colSize; - realtype *col_j; - - switch (A->type) { - - case SUNDIALS_DENSE: - - for (j=0; jN; j++) { - col_j = A->cols[j]; - for (i=0; iM; i++) - col_j[i] = ZERO; - } - - break; - - case SUNDIALS_BAND: - - colSize = A->mu + A->ml + 1; - for (j=0; jM; j++) { - col_j = A->cols[j] + A->s_mu - A->mu; - for (i=0; itype) { - - case SUNDIALS_DENSE: - - printf("\n"); - for (i=0; i < A->M; i++) { - for (j=0; j < A->N; j++) { -#if defined(SUNDIALS_EXTENDED_PRECISION) - printf("%12Lg ", DENSE_ELEM(A,i,j)); -#elif defined(SUNDIALS_DOUBLE_PRECISION) - printf("%12lg ", DENSE_ELEM(A,i,j)); -#else - printf("%12g ", DENSE_ELEM(A,i,j)); -#endif - } - printf("\n"); - } - printf("\n"); - - break; - - case SUNDIALS_BAND: - - a = A->cols; - printf("\n"); - for (i=0; i < A->N; i++) { - start = MAX(0,i-A->ml); - finish = MIN(A->N-1,i+A->mu); - for (j=0; j < start; j++) printf("%12s ",""); - for (j=start; j <= finish; j++) { -#if defined(SUNDIALS_EXTENDED_PRECISION) - printf("%12Lg ", a[j][i-j+A->s_mu]); -#elif defined(SUNDIALS_DOUBLE_PRECISION) - printf("%12lg ", a[j][i-j+A->s_mu]); -#else - printf("%12g ", a[j][i-j+A->s_mu]); -#endif - } - printf("\n"); - } - printf("\n"); - - break; - - } - -} - - diff --git a/src/amuse/community/secularmultiple/src/cvode/sundials_direct.h b/src/amuse/community/secularmultiple/src/cvode/sundials_direct.h deleted file mode 100755 index 19f6744406..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/sundials_direct.h +++ /dev/null @@ -1,323 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.3 $ - * $Date: 2009/02/17 02:39:26 $ - * ----------------------------------------------------------------- - * Programmer: Radu Serban @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2006, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This header file contains definitions and declarations for use by - * generic direct linear solvers for Ax = b. It defines types for - * dense and banded matrices and corresponding accessor macros. - * ----------------------------------------------------------------- - */ - -#ifndef _SUNDIALS_DIRECT_H -#define _SUNDIALS_DIRECT_H - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -#include "sundials_types.h" - -/* - * ================================================================= - * C O N S T A N T S - * ================================================================= - */ - -/* - * SUNDIALS_DENSE: dense matrix - * SUNDIALS_BAND: banded matrix - */ - -#define SUNDIALS_DENSE 1 -#define SUNDIALS_BAND 2 - -/* - * ================================================================== - * Type definitions - * ================================================================== - */ - -/* - * ----------------------------------------------------------------- - * Type : DlsMat - * ----------------------------------------------------------------- - * The type DlsMat is defined to be a pointer to a structure - * with various sizes, a data field, and an array of pointers to - * the columns which defines a dense or band matrix for use in - * direct linear solvers. The M and N fields indicates the number - * of rows and columns, respectively. The data field is a one - * dimensional array used for component storage. The cols field - * stores the pointers in data for the beginning of each column. - * ----------------------------------------------------------------- - * For DENSE matrices, the relevant fields in DlsMat are: - * type = SUNDIALS_DENSE - * M - number of rows - * N - number of columns - * ldim - leading dimension (ldim >= M) - * data - pointer to a contiguous block of realtype variables - * ldata - length of the data array =ldim*N - * cols - array of pointers. cols[j] points to the first element - * of the j-th column of the matrix in the array data. - * - * The elements of a dense matrix are stored columnwise (i.e columns - * are stored one on top of the other in memory). - * If A is of type DlsMat, then the (i,j)th element of A (with - * 0 <= i < M and 0 <= j < N) is given by (A->data)[j*n+i]. - * - * The DENSE_COL and DENSE_ELEM macros below allow a user to access - * efficiently individual matrix elements without writing out explicit - * data structure references and without knowing too much about the - * underlying element storage. The only storage assumption needed is - * that elements are stored columnwise and that a pointer to the - * jth column of elements can be obtained via the DENSE_COL macro. - * ----------------------------------------------------------------- - * For BAND matrices, the relevant fields in DlsMat are: - * type = SUNDIALS_BAND - * M - number of rows - * N - number of columns - * mu - upper bandwidth, 0 <= mu <= min(M,N) - * ml - lower bandwidth, 0 <= ml <= min(M,N) - * s_mu - storage upper bandwidth, mu <= s_mu <= N-1. - * The dgbtrf routine writes the LU factors into the storage - * for A. The upper triangular factor U, however, may have - * an upper bandwidth as big as MIN(N-1,mu+ml) because of - * partial pivoting. The s_mu field holds the upper - * bandwidth allocated for A. - * ldim - leading dimension (ldim >= s_mu) - * data - pointer to a contiguous block of realtype variables - * ldata - length of the data array =ldim*(s_mu+ml+1) - * cols - array of pointers. cols[j] points to the first element - * of the j-th column of the matrix in the array data. - * - * The BAND_COL, BAND_COL_ELEM, and BAND_ELEM macros below allow a - * user to access individual matrix elements without writing out - * explicit data structure references and without knowing too much - * about the underlying element storage. The only storage assumption - * needed is that elements are stored columnwise and that a pointer - * into the jth column of elements can be obtained via the BAND_COL - * macro. The BAND_COL_ELEM macro selects an element from a column - * which has already been isolated via BAND_COL. The macro - * BAND_COL_ELEM allows the user to avoid the translation - * from the matrix location (i,j) to the index in the array returned - * by BAND_COL at which the (i,j)th element is stored. - * ----------------------------------------------------------------- - */ - -typedef struct _DlsMat { - int type; - int M; - int N; - int ldim; - int mu; - int ml; - int s_mu; - realtype *data; - int ldata; - realtype **cols; -} *DlsMat; - -/* - * ================================================================== - * Data accessor macros - * ================================================================== - */ - -/* - * ----------------------------------------------------------------- - * DENSE_COL and DENSE_ELEM - * ----------------------------------------------------------------- - * - * DENSE_COL(A,j) references the jth column of the M-by-N dense - * matrix A, 0 <= j < N. The type of the expression DENSE_COL(A,j) - * is (realtype *). After the assignment in the usage above, col_j - * may be treated as an array indexed from 0 to M-1. The (i,j)-th - * element of A is thus referenced by col_j[i]. - * - * DENSE_ELEM(A,i,j) references the (i,j)th element of the dense - * M-by-N matrix A, 0 <= i < M ; 0 <= j < N. - * - * ----------------------------------------------------------------- - */ - -#define DENSE_COL(A,j) ((A->cols)[j]) -#define DENSE_ELEM(A,i,j) ((A->cols)[j][i]) - -/* - * ----------------------------------------------------------------- - * BAND_COL, BAND_COL_ELEM, and BAND_ELEM - * ----------------------------------------------------------------- - * - * BAND_COL(A,j) references the diagonal element of the jth column - * of the N by N band matrix A, 0 <= j <= N-1. The type of the - * expression BAND_COL(A,j) is realtype *. The pointer returned by - * the call BAND_COL(A,j) can be treated as an array which is - * indexed from -(A->mu) to (A->ml). - * - * BAND_COL_ELEM references the (i,j)th entry of the band matrix A - * when used in conjunction with BAND_COL. The index (i,j) should - * satisfy j-(A->mu) <= i <= j+(A->ml). - * - * BAND_ELEM(A,i,j) references the (i,j)th element of the M-by-N - * band matrix A, where 0 <= i,j <= N-1. The location (i,j) should - * further satisfy j-(A->mu) <= i <= j+(A->ml). - * - * ----------------------------------------------------------------- - */ - -#define BAND_COL(A,j) (((A->cols)[j])+(A->s_mu)) -#define BAND_COL_ELEM(col_j,i,j) (col_j[(i)-(j)]) -#define BAND_ELEM(A,i,j) ((A->cols)[j][(i)-(j)+(A->s_mu)]) - -/* - * ================================================================== - * Exported function prototypes (functions working on dlsMat) - * ================================================================== - */ - -/* - * ----------------------------------------------------------------- - * Function: NewDenseMat - * ----------------------------------------------------------------- - * NewDenseMat allocates memory for an M-by-N dense matrix and - * returns the storage allocated (type DlsMat). NewDenseMat - * returns NULL if the request for matrix storage cannot be - * satisfied. See the above documentation for the type DlsMat - * for matrix storage details. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT DlsMat NewDenseMat(int M, int N); - -/* - * ----------------------------------------------------------------- - * Function: NewBandMat - * ----------------------------------------------------------------- - * NewBandMat allocates memory for an M-by-N band matrix - * with upper bandwidth mu, lower bandwidth ml, and storage upper - * bandwidth smu. Pass smu as follows depending on whether A will - * be LU factored: - * - * (1) Pass smu = mu if A will not be factored. - * - * (2) Pass smu = MIN(N-1,mu+ml) if A will be factored. - * - * NewBandMat returns the storage allocated (type DlsMat) or - * NULL if the request for matrix storage cannot be satisfied. - * See the documentation for the type DlsMat for matrix storage - * details. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT DlsMat NewBandMat(int N, int mu, int ml, int smu); - -/* - * ----------------------------------------------------------------- - * Functions: DestroyMat - * ----------------------------------------------------------------- - * DestroyMat frees the memory allocated by NewDenseMat or NewBandMat - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void DestroyMat(DlsMat A); - -/* - * ----------------------------------------------------------------- - * Function: NewIntArray - * ----------------------------------------------------------------- - * NewIntArray allocates memory an array of N integers and returns - * the pointer to the memory it allocates. If the request for - * memory storage cannot be satisfied, it returns NULL. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT int *NewIntArray(int N); - -/* - * ----------------------------------------------------------------- - * Function: NewRealArray - * ----------------------------------------------------------------- - * NewRealArray allocates memory an array of N realtype and returns - * the pointer to the memory it allocates. If the request for - * memory storage cannot be satisfied, it returns NULL. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT realtype *NewRealArray(int N); - -/* - * ----------------------------------------------------------------- - * Function: DestroyArray - * ----------------------------------------------------------------- - * DestroyArray frees memory allocated by NewIntArray or by - * NewRealArray. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void DestroyArray(void *p); - -/* - * ----------------------------------------------------------------- - * Function : AddIdentity - * ----------------------------------------------------------------- - * AddIdentity adds 1.0 to the main diagonal (A_ii, i=1,2,...,N-1) of - * the M-by-N matrix A (M>= N) and stores the result back in A. - * AddIdentity is typically used with square matrices. - * AddIdentity does not check for M >= N and therefore a segmentation - * fault will occur if M < N! - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void AddIdentity(DlsMat A); - -/* - * ----------------------------------------------------------------- - * Function : SetToZero - * ----------------------------------------------------------------- - * SetToZero sets all the elements of the M-by-N matrix A to 0.0. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void SetToZero(DlsMat A); - -/* - * ----------------------------------------------------------------- - * Functions: PrintMat - * ----------------------------------------------------------------- - * This function prints the M-by-N (dense or band) matrix A to - * standard output as it would normally appear on paper. - * It is intended as debugging tools with small values of M and N. - * The elements are printed using the %g/%lg/%Lg option. - * A blank line is printed before and after the matrix. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void PrintMat(DlsMat A); - - -/* - * ================================================================== - * Exported function prototypes (functions working on realtype**) - * ================================================================== - */ - -SUNDIALS_EXPORT realtype **newDenseMat(int m, int n); -SUNDIALS_EXPORT realtype **newBandMat(int n, int smu, int ml); -SUNDIALS_EXPORT void destroyMat(realtype **a); -SUNDIALS_EXPORT int *newIntArray(int n); -SUNDIALS_EXPORT realtype *newRealArray(int m); -SUNDIALS_EXPORT void destroyArray(void *v); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/amuse/community/secularmultiple/src/cvode/sundials_math.c b/src/amuse/community/secularmultiple/src/cvode/sundials_math.c deleted file mode 100755 index 4865cfc324..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/sundials_math.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.1 $ - * $Date: 2006/07/05 15:32:38 $ - * ----------------------------------------------------------------- - * Programmer(s): Scott D. Cohen, Alan C. Hindmarsh and - * Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the implementation file for a simple C-language math - * library. - * ----------------------------------------------------------------- - */ - -#include -#include -#include - -#include "sundials_math.h" - -#define ZERO RCONST(0.0) -#define ONE RCONST(1.0) - -realtype RPowerI(realtype base, int exponent) -{ - int i, expt; - realtype prod; - - prod = ONE; - expt = abs(exponent); - for(i = 1; i <= expt; i++) prod *= base; - if (exponent < 0) prod = ONE/prod; - return(prod); -} - -realtype RPowerR(realtype base, realtype exponent) -{ - if (base <= ZERO) return(ZERO); - -#if defined(SUNDIALS_USE_GENERIC_MATH) - return((realtype) pow((double) base, (double) exponent)); -#elif defined(SUNDIALS_DOUBLE_PRECISION) - return(pow(base, exponent)); -#elif defined(SUNDIALS_SINGLE_PRECISION) - return(powf(base, exponent)); -#elif defined(SUNDIALS_EXTENDED_PRECISION) - return(powl(base, exponent)); -#endif -} - -realtype RSqrt(realtype x) -{ - if (x <= ZERO) return(ZERO); - -#if defined(SUNDIALS_USE_GENERIC_MATH) - return((realtype) sqrt((double) x)); -#elif defined(SUNDIALS_DOUBLE_PRECISION) - return(sqrt(x)); -#elif defined(SUNDIALS_SINGLE_PRECISION) - return(sqrtf(x)); -#elif defined(SUNDIALS_EXTENDED_PRECISION) - return(sqrtl(x)); -#endif -} - -realtype RAbs(realtype x) -{ -#if defined(SUNDIALS_USE_GENERIC_MATH) - return((realtype) fabs((double) x)); -#elif defined(SUNDIALS_DOUBLE_PRECISION) - return(fabs(x)); -#elif defined(SUNDIALS_SINGLE_PRECISION) - return(fabsf(x)); -#elif defined(SUNDIALS_EXTENDED_PRECISION) - return(fabsl(x)); -#endif -} - -realtype RExp(realtype x) -{ -#if defined(SUNDIALS_USE_GENERIC_MATH) - return((realtype) exp((double) x)); -#elif defined(SUNDIALS_DOUBLE_PRECISION) - return(exp(x)); -#elif defined(SUNDIALS_SINGLE_PRECISION) - return(expf(x)); -#elif defined(SUNDIALS_EXTENDED_PRECISION) - return(expl(x)); -#endif -} diff --git a/src/amuse/community/secularmultiple/src/cvode/sundials_math.h b/src/amuse/community/secularmultiple/src/cvode/sundials_math.h deleted file mode 100755 index 87feda0595..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/sundials_math.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.2 $ - * $Date: 2006/11/29 00:05:07 $ - * ----------------------------------------------------------------- - * Programmer(s): Scott D. Cohen, Alan C. Hindmarsh and - * Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the header file for a simple C-language math library. The - * routines listed here work with the type realtype as defined in - * the header file sundials_types.h. - * ----------------------------------------------------------------- - */ - -#ifndef _SUNDIALSMATH_H -#define _SUNDIALSMATH_H - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -#include "sundials_types.h" - -/* - * ----------------------------------------------------------------- - * Macros : MIN and MAX - * ----------------------------------------------------------------- - * MIN(A,B) returns the minimum of A and B - * - * MAX(A,B) returns the maximum of A and B - * - * SQR(A) returns A^2 - * ----------------------------------------------------------------- - */ - -#ifndef MIN -#define MIN(A, B) ((A) < (B) ? (A) : (B)) -#endif - -#ifndef MAX -#define MAX(A, B) ((A) > (B) ? (A) : (B)) -#endif - -#ifndef SQR -#define SQR(A) ((A)*(A)) -#endif - -#ifndef ABS -#define ABS RAbs -#endif - -#ifndef SQRT -#define SQRT RSqrt -#endif - -#ifndef EXP -#define EXP RExp -#endif - -/* - * ----------------------------------------------------------------- - * Function : RPowerI - * ----------------------------------------------------------------- - * Usage : int exponent; - * realtype base, ans; - * ans = RPowerI(base,exponent); - * ----------------------------------------------------------------- - * RPowerI returns the value of base^exponent, where base is of type - * realtype and exponent is of type int. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT realtype RPowerI(realtype base, int exponent); - -/* - * ----------------------------------------------------------------- - * Function : RPowerR - * ----------------------------------------------------------------- - * Usage : realtype base, exponent, ans; - * ans = RPowerR(base,exponent); - * ----------------------------------------------------------------- - * RPowerR returns the value of base^exponent, where both base and - * exponent are of type realtype. If base < ZERO, then RPowerR - * returns ZERO. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT realtype RPowerR(realtype base, realtype exponent); - -/* - * ----------------------------------------------------------------- - * Function : RSqrt - * ----------------------------------------------------------------- - * Usage : realtype sqrt_x; - * sqrt_x = RSqrt(x); - * ----------------------------------------------------------------- - * RSqrt(x) returns the square root of x. If x < ZERO, then RSqrt - * returns ZERO. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT realtype RSqrt(realtype x); - -/* - * ----------------------------------------------------------------- - * Function : RAbs (a.k.a. ABS) - * ----------------------------------------------------------------- - * Usage : realtype abs_x; - * abs_x = RAbs(x); - * ----------------------------------------------------------------- - * RAbs(x) returns the absolute value of x. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT realtype RAbs(realtype x); - -/* - * ----------------------------------------------------------------- - * Function : RExp (a.k.a. EXP) - * ----------------------------------------------------------------- - * Usage : realtype exp_x; - * exp_x = RExp(x); - * ----------------------------------------------------------------- - * RExp(x) returns e^x (base-e exponential function). - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT realtype RExp(realtype x); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/amuse/community/secularmultiple/src/cvode/sundials_nvector.c b/src/amuse/community/secularmultiple/src/cvode/sundials_nvector.c deleted file mode 100755 index d9c3c4bb12..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/sundials_nvector.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.3 $ - * $Date: 2007/04/06 20:33:30 $ - * ----------------------------------------------------------------- - * Programmer(s): Radu Serban and Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the implementation file for a generic NVECTOR package. - * It contains the implementation of the N_Vector operations listed - * in nvector.h. - * ----------------------------------------------------------------- - */ - -#include - -#include "sundials_nvector.h" - -/* - * ----------------------------------------------------------------- - * Functions in the 'ops' structure - * ----------------------------------------------------------------- - */ - -N_Vector N_VClone(N_Vector w) -{ - N_Vector v = NULL; - v = w->ops->nvclone(w); - return(v); -} - -N_Vector N_VCloneEmpty(N_Vector w) -{ - N_Vector v = NULL; - v = w->ops->nvcloneempty(w); - return(v); -} - -void N_VDestroy(N_Vector v) -{ - if (v==NULL) return; - v->ops->nvdestroy(v); - return; -} - -void N_VSpace(N_Vector v, long int *lrw, long int *liw) -{ - v->ops->nvspace(v, lrw, liw); - return; -} - -realtype *N_VGetArrayPointer(N_Vector v) -{ - return((realtype *) v->ops->nvgetarraypointer(v)); -} - -void N_VSetArrayPointer(realtype *v_data, N_Vector v) -{ - v->ops->nvsetarraypointer(v_data, v); - return; -} - -void N_VLinearSum(realtype a, N_Vector x, realtype b, N_Vector y, N_Vector z) -{ - z->ops->nvlinearsum(a, x, b, y, z); - return; -} - -void N_VConst(realtype c, N_Vector z) -{ - z->ops->nvconst(c, z); - return; -} - -void N_VProd(N_Vector x, N_Vector y, N_Vector z) -{ - z->ops->nvprod(x, y, z); - return; -} - -void N_VDiv(N_Vector x, N_Vector y, N_Vector z) -{ - z->ops->nvdiv(x, y, z); - return; -} - -void N_VScale(realtype c, N_Vector x, N_Vector z) -{ - z->ops->nvscale(c, x, z); - return; -} - -void N_VAbs(N_Vector x, N_Vector z) -{ - z->ops->nvabs(x, z); - return; -} - -void N_VInv(N_Vector x, N_Vector z) -{ - z->ops->nvinv(x, z); - return; -} - -void N_VAddConst(N_Vector x, realtype b, N_Vector z) -{ - z->ops->nvaddconst(x, b, z); - return; -} - -realtype N_VDotProd(N_Vector x, N_Vector y) -{ - return((realtype) y->ops->nvdotprod(x, y)); -} - -realtype N_VMaxNorm(N_Vector x) -{ - return((realtype) x->ops->nvmaxnorm(x)); -} - -realtype N_VWrmsNorm(N_Vector x, N_Vector w) -{ - return((realtype) x->ops->nvwrmsnorm(x, w)); -} - -realtype N_VWrmsNormMask(N_Vector x, N_Vector w, N_Vector id) -{ - return((realtype) x->ops->nvwrmsnormmask(x, w, id)); -} - -realtype N_VMin(N_Vector x) -{ - return((realtype) x->ops->nvmin(x)); -} - -realtype N_VWL2Norm(N_Vector x, N_Vector w) -{ - return((realtype) x->ops->nvwl2norm(x, w)); -} - -realtype N_VL1Norm(N_Vector x) -{ - return((realtype) x->ops->nvl1norm(x)); -} - -void N_VCompare(realtype c, N_Vector x, N_Vector z) -{ - z->ops->nvcompare(c, x, z); - return; -} - -booleantype N_VInvTest(N_Vector x, N_Vector z) -{ - return((booleantype) z->ops->nvinvtest(x, z)); -} - -booleantype N_VConstrMask(N_Vector c, N_Vector x, N_Vector m) -{ - return((booleantype) x->ops->nvconstrmask(c, x, m)); -} - -realtype N_VMinQuotient(N_Vector num, N_Vector denom) -{ - return((realtype) num->ops->nvminquotient(num, denom)); -} - -/* - * ----------------------------------------------------------------- - * Additional functions exported by the generic NVECTOR: - * N_VCloneEmptyVectorArray - * N_VCloneVectorArray - * N_VDestroyVectorArray - * ----------------------------------------------------------------- - */ - -N_Vector *N_VCloneEmptyVectorArray(int count, N_Vector w) -{ - N_Vector *vs = NULL; - int j; - - if (count <= 0) return(NULL); - - vs = (N_Vector *) malloc(count * sizeof(N_Vector)); - if(vs == NULL) return(NULL); - - for (j = 0; j < count; j++) { - vs[j] = N_VCloneEmpty(w); - if (vs[j] == NULL) { - N_VDestroyVectorArray(vs, j-1); - return(NULL); - } - } - - return(vs); -} - -N_Vector *N_VCloneVectorArray(int count, N_Vector w) -{ - N_Vector *vs = NULL; - int j; - - if (count <= 0) return(NULL); - - vs = (N_Vector *) malloc(count * sizeof(N_Vector)); - if(vs == NULL) return(NULL); - - for (j = 0; j < count; j++) { - vs[j] = N_VClone(w); - if (vs[j] == NULL) { - N_VDestroyVectorArray(vs, j-1); - return(NULL); - } - } - - return(vs); -} - -void N_VDestroyVectorArray(N_Vector *vs, int count) -{ - int j; - - if (vs==NULL) return; - - for (j = 0; j < count; j++) N_VDestroy(vs[j]); - - free(vs); vs = NULL; - - return; -} diff --git a/src/amuse/community/secularmultiple/src/cvode/sundials_nvector.h b/src/amuse/community/secularmultiple/src/cvode/sundials_nvector.h deleted file mode 100755 index 08293ad959..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/sundials_nvector.h +++ /dev/null @@ -1,373 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.2 $ - * $Date: 2006/11/29 00:05:07 $ - * ----------------------------------------------------------------- - * Programmer(s): Radu Serban and Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - * ----------------------------------------------------------------- - * This is the header file for a generic NVECTOR package. - * It defines the N_Vector structure (_generic_N_Vector) which - * contains the following fields: - * - an implementation-dependent 'content' field which contains - * the description and actual data of the vector - * - an 'ops' filed which contains a structure listing operations - * acting on such vectors - * - * Part I of this file contains type declarations for the - * _generic_N_Vector and _generic_N_Vector_Ops structures, as well - * as references to pointers to such structures (N_Vector). - * - * Part II of this file contains the prototypes for the vector - * functions which operate on N_Vector. - * - * At a minimum, a particular implementation of an NVECTOR must - * do the following: - * - specify the 'content' field of N_Vector, - * - implement the operations on those N_Vectors, - * - provide a constructor routine for new vectors - * - * Additionally, an NVECTOR implementation may provide the following: - * - macros to access the underlying N_Vector data - * - a constructor for an array of N_Vectors - * - a constructor for an empty N_Vector (i.e., a new N_Vector with - * a NULL data pointer). - * - a routine to print the content of an N_Vector - * ----------------------------------------------------------------- - */ - -#ifndef _NVECTOR_H -#define _NVECTOR_H - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -#include "sundials_types.h" - -/* - * ----------------------------------------------------------------- - * Generic definition of N_Vector - * ----------------------------------------------------------------- - */ - -/* Forward reference for pointer to N_Vector_Ops object */ -typedef struct _generic_N_Vector_Ops *N_Vector_Ops; - -/* Forward reference for pointer to N_Vector object */ -typedef struct _generic_N_Vector *N_Vector; - -/* Define array of N_Vectors */ -typedef N_Vector *N_Vector_S; - -/* Structure containing function pointers to vector operations */ -struct _generic_N_Vector_Ops { - N_Vector (*nvclone)(N_Vector); - N_Vector (*nvcloneempty)(N_Vector); - void (*nvdestroy)(N_Vector); - void (*nvspace)(N_Vector, long int *, long int *); - realtype* (*nvgetarraypointer)(N_Vector); - void (*nvsetarraypointer)(realtype *, N_Vector); - void (*nvlinearsum)(realtype, N_Vector, realtype, N_Vector, N_Vector); - void (*nvconst)(realtype, N_Vector); - void (*nvprod)(N_Vector, N_Vector, N_Vector); - void (*nvdiv)(N_Vector, N_Vector, N_Vector); - void (*nvscale)(realtype, N_Vector, N_Vector); - void (*nvabs)(N_Vector, N_Vector); - void (*nvinv)(N_Vector, N_Vector); - void (*nvaddconst)(N_Vector, realtype, N_Vector); - realtype (*nvdotprod)(N_Vector, N_Vector); - realtype (*nvmaxnorm)(N_Vector); - realtype (*nvwrmsnorm)(N_Vector, N_Vector); - realtype (*nvwrmsnormmask)(N_Vector, N_Vector, N_Vector); - realtype (*nvmin)(N_Vector); - realtype (*nvwl2norm)(N_Vector, N_Vector); - realtype (*nvl1norm)(N_Vector); - void (*nvcompare)(realtype, N_Vector, N_Vector); - booleantype (*nvinvtest)(N_Vector, N_Vector); - booleantype (*nvconstrmask)(N_Vector, N_Vector, N_Vector); - realtype (*nvminquotient)(N_Vector, N_Vector); -}; - -/* - * ----------------------------------------------------------------- - * A vector is a structure with an implementation-dependent - * 'content' field, and a pointer to a structure of vector - * operations corresponding to that implementation. - * ----------------------------------------------------------------- - */ - -struct _generic_N_Vector { - void *content; - struct _generic_N_Vector_Ops *ops; -}; - -/* - * ----------------------------------------------------------------- - * Functions exported by NVECTOR module - * ----------------------------------------------------------------- - */ - -/* - * ----------------------------------------------------------------- - * N_VClone - * Creates a new vector of the same type as an existing vector. - * It does not copy the vector, but rather allocates storage for - * the new vector. - * - * N_VCloneEmpty - * Creates a new vector of the same type as an existing vector, - * but does not allocate storage. - * - * N_VDestroy - * Destroys a vector created with N_VClone. - * - * N_VSpace - * Returns space requirements for one N_Vector (type 'realtype' in - * lrw and type 'long int' in liw). - * - * N_VGetArrayPointer - * Returns a pointer to the data component of the given N_Vector. - * NOTE: This function assumes that the internal data is stored - * as a contiguous 'realtype' array. This routine is only used in - * the solver-specific interfaces to the dense and banded linear - * solvers, as well as the interfaces to the banded preconditioners - * distributed with SUNDIALS. - * - * N_VSetArrayPointer - * Overwrites the data field in the given N_Vector with a user-supplied - * array of type 'realtype'. - * NOTE: This function assumes that the internal data is stored - * as a contiguous 'realtype' array. This routine is only used in - * the interfaces to the dense linear solver. - * - * N_VLinearSum - * Performs the operation z = a*x + b*y - * - * N_VConst - * Performs the operation z[i] = c for i = 0, 1, ..., N-1 - * - * N_VProd - * Performs the operation z[i] = x[i]*y[i] for i = 0, 1, ..., N-1 - * - * N_VDiv - * Performs the operation z[i] = x[i]/y[i] for i = 0, 1, ..., N-1 - * - * N_VScale - * Performs the operation z = c*x - * - * N_VAbs - * Performs the operation z[i] = |x[i]| for i = 0, 1, ..., N-1 - * - * N_VInv - * Performs the operation z[i] = 1/x[i] for i = 0, 1, ..., N-1 - * This routine does not check for division by 0. It should be - * called only with an N_Vector x which is guaranteed to have - * all non-zero components. - * - * N_VAddConst - * Performs the operation z[i] = x[i] + b for i = 0, 1, ..., N-1 - * - * N_VDotProd - * Returns the dot product of two vectors: - * sum (i = 0 to N-1) {x[i]*y[i]} - * - * N_VMaxNorm - * Returns the maximum norm of x: - * max (i = 0 to N-1) ABS(x[i]) - * - * N_VWrmsNorm - * Returns the weighted root mean square norm of x with weight - * vector w: - * sqrt [(sum (i = 0 to N-1) {(x[i]*w[i])^2})/N] - * - * N_VWrmsNormMask - * Returns the weighted root mean square norm of x with weight - * vector w, masked by the elements of id: - * sqrt [(sum (i = 0 to N-1) {(x[i]*w[i]*msk[i])^2})/N] - * where msk[i] = 1.0 if id[i] > 0 and - * msk[i] = 0.0 if id[i] < 0 - * - * N_VMin - * Returns the smallest element of x: - * min (i = 0 to N-1) x[i] - * - * N_VWL2Norm - * Returns the weighted Euclidean L2 norm of x with weight - * vector w: - * sqrt [(sum (i = 0 to N-1) {(x[i]*w[i])^2})] - * - * N_VL1Norm - * Returns the L1 norm of x: - * sum (i = 0 to N-1) {ABS(x[i])} - * - * N_VCompare - * Performs the operation - * z[i] = 1.0 if ABS(x[i]) >= c i = 0, 1, ..., N-1 - * 0.0 otherwise - * - * N_VInvTest - * Performs the operation z[i] = 1/x[i] with a test for - * x[i] == 0.0 before inverting x[i]. - * This routine returns TRUE if all components of x are non-zero - * (successful inversion) and returns FALSE otherwise. - * - * N_VConstrMask - * Performs the operation : - * m[i] = 1.0 if constraint test fails for x[i] - * m[i] = 0.0 if constraint test passes for x[i] - * where the constraint tests are as follows: - * If c[i] = +2.0, then x[i] must be > 0.0. - * If c[i] = +1.0, then x[i] must be >= 0.0. - * If c[i] = -1.0, then x[i] must be <= 0.0. - * If c[i] = -2.0, then x[i] must be < 0.0. - * This routine returns a boolean FALSE if any element failed - * the constraint test, TRUE if all passed. It also sets a - * mask vector m, with elements equal to 1.0 where the - * corresponding constraint test failed, and equal to 0.0 - * where the constraint test passed. - * This routine is specialized in that it is used only for - * constraint checking. - * - * N_VMinQuotient - * Performs the operation : - * minq = min ( num[i]/denom[i]) over all i such that - * denom[i] != 0. - * This routine returns the minimum of the quotients obtained - * by term-wise dividing num[i] by denom[i]. A zero element - * in denom will be skipped. If no such quotients are found, - * then the large value BIG_REAL is returned. - * - * ----------------------------------------------------------------- - * - * The following table lists the vector functions used by - * different modules in SUNDIALS. The symbols in the table - * have the following meaning: - * S - called by the solver; - * D - called by the dense linear solver module - * B - called by the band linear solver module - * Di - called by the diagonal linear solver module - * I - called by the iterative linear solver module - * BP - called by the band preconditioner module - * BBDP - called by the band-block diagonal preconditioner module - * F - called by the Fortran-to-C interface - * - * ------------------------------------------------ - * MODULES - * NVECTOR ------------------------------------------------ - * FUNCTIONS CVODE/CVODES IDA KINSOL - * ----------------------------------------------------------------- - * N_VClone S Di I S I BBDP S I BBDP - * ----------------------------------------------------------------- - * N_VCloneEmpty F F F - * ----------------------------------------------------------------- - * N_VDestroy S Di I S I BBDP S I BBDP - * ----------------------------------------------------------------- - * N_VSpace S S S - * ----------------------------------------------------------------- - * N_VGetArrayPointer D B BP BBDP F D B BBDP BBDP F - * ----------------------------------------------------------------- - * N_VSetArrayPointer D F D F - * ----------------------------------------------------------------- - * N_VLinearSum S D Di I S D I S I - * ----------------------------------------------------------------- - * N_VConst S I S I I - * ----------------------------------------------------------------- - * N_VProd S Di I S I S I - * ----------------------------------------------------------------- - * N_VDiv S Di I S I S I - * ----------------------------------------------------------------- - * N_VScale S D B Di I BP BBDP S D B I BBDP S I BBDP - * ----------------------------------------------------------------- - * N_VAbs S S S - * ----------------------------------------------------------------- - * N_VInv S Di S S - * ----------------------------------------------------------------- - * N_VAddConst S Di S - * ----------------------------------------------------------------- - * N_VDotProd I I I - * ----------------------------------------------------------------- - * N_VMaxNorm S S S - * ----------------------------------------------------------------- - * N_VWrmsNorm S D B I BP BBDP S - * ----------------------------------------------------------------- - * N_VWrmsNormMask S - * ----------------------------------------------------------------- - * N_VMin S S S - * ----------------------------------------------------------------- - * N_VWL2Norm S I - * ----------------------------------------------------------------- - * N_VL1Norm I - * ----------------------------------------------------------------- - * N_VCompare Di S - * ----------------------------------------------------------------- - * N_VInvTest Di - * ----------------------------------------------------------------- - * N_VConstrMask S S - * ----------------------------------------------------------------- - * N_VMinQuotient S S - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT N_Vector N_VClone(N_Vector w); -SUNDIALS_EXPORT N_Vector N_VCloneEmpty(N_Vector w); -SUNDIALS_EXPORT void N_VDestroy(N_Vector v); -SUNDIALS_EXPORT void N_VSpace(N_Vector v, long int *lrw, long int *liw); -SUNDIALS_EXPORT realtype *N_VGetArrayPointer(N_Vector v); -SUNDIALS_EXPORT void N_VSetArrayPointer(realtype *v_data, N_Vector v); -SUNDIALS_EXPORT void N_VLinearSum(realtype a, N_Vector x, realtype b, N_Vector y, N_Vector z); -SUNDIALS_EXPORT void N_VConst(realtype c, N_Vector z); -SUNDIALS_EXPORT void N_VProd(N_Vector x, N_Vector y, N_Vector z); -SUNDIALS_EXPORT void N_VDiv(N_Vector x, N_Vector y, N_Vector z); -SUNDIALS_EXPORT void N_VScale(realtype c, N_Vector x, N_Vector z); -SUNDIALS_EXPORT void N_VAbs(N_Vector x, N_Vector z); -SUNDIALS_EXPORT void N_VInv(N_Vector x, N_Vector z); -SUNDIALS_EXPORT void N_VAddConst(N_Vector x, realtype b, N_Vector z); -SUNDIALS_EXPORT realtype N_VDotProd(N_Vector x, N_Vector y); -SUNDIALS_EXPORT realtype N_VMaxNorm(N_Vector x); -SUNDIALS_EXPORT realtype N_VWrmsNorm(N_Vector x, N_Vector w); -SUNDIALS_EXPORT realtype N_VWrmsNormMask(N_Vector x, N_Vector w, N_Vector id); -SUNDIALS_EXPORT realtype N_VMin(N_Vector x); -SUNDIALS_EXPORT realtype N_VWL2Norm(N_Vector x, N_Vector w); -SUNDIALS_EXPORT realtype N_VL1Norm(N_Vector x); -SUNDIALS_EXPORT void N_VCompare(realtype c, N_Vector x, N_Vector z); -SUNDIALS_EXPORT booleantype N_VInvTest(N_Vector x, N_Vector z); -SUNDIALS_EXPORT booleantype N_VConstrMask(N_Vector c, N_Vector x, N_Vector m); -SUNDIALS_EXPORT realtype N_VMinQuotient(N_Vector num, N_Vector denom); - -/* - * ----------------------------------------------------------------- - * Additional functions exported by NVECTOR module - * ----------------------------------------------------------------- - */ - -/* - * ----------------------------------------------------------------- - * N_VCloneEmptyVectorArray - * Creates (by cloning 'w') an array of 'count' empty N_Vectors - * - * N_VCloneVectorArray - * Creates (by cloning 'w') an array of 'count' N_Vectors - * - * N_VDestroyVectorArray - * Frees memory for an array of 'count' N_Vectors that was - * created by a call to N_VCloneVectorArray - * - * These functions are used by the SPGMR iterative linear solver - * module and by the CVODES and IDAS solvers. - * ----------------------------------------------------------------- - */ - -SUNDIALS_EXPORT N_Vector *N_VCloneEmptyVectorArray(int count, N_Vector w); -SUNDIALS_EXPORT N_Vector *N_VCloneVectorArray(int count, N_Vector w); -SUNDIALS_EXPORT void N_VDestroyVectorArray(N_Vector *vs, int count); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/amuse/community/secularmultiple/src/cvode/sundials_types.h b/src/amuse/community/secularmultiple/src/cvode/sundials_types.h deleted file mode 100755 index bf1c5e4d7c..0000000000 --- a/src/amuse/community/secularmultiple/src/cvode/sundials_types.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * ----------------------------------------------------------------- - * $Revision: 1.2 $ - * $Date: 2006/11/29 00:05:07 $ - * ----------------------------------------------------------------- - * Programmer(s): Scott Cohen, Alan Hindmarsh, Radu Serban, and - * Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * Copyright (c) 2002, The Regents of the University of California. - * Produced at the Lawrence Livermore National Laboratory. - * All rights reserved. - * For details, see the LICENSE file. - *------------------------------------------------------------------ - * This header file exports two types: realtype and booleantype, - * as well as the constants TRUE and FALSE. - * - * Users should include the header file sundials_types.h in every - * program file and use the exported name realtype instead of - * float, double or long double. - * - * The constants SUNDIALS_SINGLE_PRECISION, SUNDIALS_DOUBLE_PRECISION - * and SUNDIALS_LONG_DOUBLE_PRECISION indicate the underlying data - * type of realtype. It is set at the configuration stage. - * - * The legal types for realtype are float, double and long double. - * - * The macro RCONST gives the user a convenient way to define - * real-valued constants. To use the constant 1.0, for example, - * the user should write the following: - * - * #define ONE RCONST(1.0) - * - * If realtype is defined as a double, then RCONST(1.0) expands - * to 1.0. If realtype is defined as a float, then RCONST(1.0) - * expands to 1.0F. If realtype is defined as a long double, - * then RCONST(1.0) expands to 1.0L. There is never a need to - * explicitly cast 1.0 to (realtype). - *------------------------------------------------------------------ - */ - -#ifndef _SUNDIALSTYPES_H -#define _SUNDIALSTYPES_H - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -#ifndef _SUNDIALS_CONFIG_H -#define _SUNDIALS_CONFIG_H -#include "sundials_config.h" -#endif - -#include "float.h" - -/* - *------------------------------------------------------------------ - * Type realtype - * Macro RCONST - * Constants BIG_REAL, SMALL_REAL, and UNIT_ROUNDOFF - *------------------------------------------------------------------ - */ - -#if defined(SUNDIALS_SINGLE_PRECISION) - -typedef float realtype; -# define RCONST(x) x##F -# define BIG_REAL FLT_MAX -# define SMALL_REAL FLT_MIN -# define UNIT_ROUNDOFF FLT_EPSILON - -#elif defined(SUNDIALS_DOUBLE_PRECISION) - -typedef double realtype; -# define RCONST(x) x -# define BIG_REAL DBL_MAX -# define SMALL_REAL DBL_MIN -# define UNIT_ROUNDOFF DBL_EPSILON - -#elif defined(SUNDIALS_EXTENDED_PRECISION) - -typedef long double realtype; -# define RCONST(x) x##L -# define BIG_REAL LDBL_MAX -# define SMALL_REAL LDBL_MIN -# define UNIT_ROUNDOFF LDBL_EPSILON - -#endif - -/* - *------------------------------------------------------------------ - * Type : booleantype - *------------------------------------------------------------------ - * Constants : FALSE and TRUE - *------------------------------------------------------------------ - * ANSI C does not have a built-in boolean data type. Below is the - * definition for a new type called booleantype. The advantage of - * using the name booleantype (instead of int) is an increase in - * code readability. It also allows the programmer to make a - * distinction between int and boolean data. Variables of type - * booleantype are intended to have only the two values FALSE and - * TRUE which are defined below to be equal to 0 and 1, - * respectively. - *------------------------------------------------------------------ - */ - -#ifndef booleantype -#define booleantype int -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/amuse/community/secularmultiple/src/evolve.cpp b/src/amuse/community/secularmultiple/src/evolve.cpp deleted file mode 100644 index b3ad552b2c..0000000000 --- a/src/amuse/community/secularmultiple/src/evolve.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* SecularMultiple */ -/* Adrian Hamers Janary 2015 */ - -#include "evolve.h" - - -int evolve(ParticlesMap *particlesMap, External_ParticlesMap *external_particlesMap, double start_time, double time_step, double *output_time, double *hamiltonian, int *output_flag, int *error_code) -{ - int N_particles = particlesMap->size(); - int N_bodies, N_binaries; - int N_root_finding; - - determine_binary_parents_and_levels(particlesMap,&N_bodies,&N_binaries,&N_root_finding); - set_binary_masses_from_body_masses(particlesMap); - -// printf("N_bodies %d N_binaries %d N_particles %d N_root_finding %d\n",N_bodies,N_binaries,N_particles,N_root_finding); - - /********************* - * setup of UserData * - ********************/ - - UserData data; - data = NULL; - data = (UserData) malloc(sizeof *data); - data->particlesMap = particlesMap; - data->external_particlesMap = external_particlesMap; - data->N_root_finding = N_root_finding; - data->start_time = start_time; - - /******************************** - * set ODE tolerances * - ********************************/ - if (relative_tolerance <= 0.0) - { - printf("relative tolerance cannot be zero; setting default value of 1e-16\n"); - relative_tolerance = 1.0e-16; - } - - /* Warning: hardcoded parameters for ODE solver */ - //double abs_tol_spin_vec = 1.0e-12; - double abs_tol_spin_vec = 1.0e4; - double abs_tol_e_vec = absolute_tolerance_eccentricity_vectors; - //abs_tol_e_vec = 1.0e-10; - double abs_tol_h_vec = 1.0e-2; - double initial_ODE_timestep = 1.0e-6; /* one year */ - int maximum_number_of_internal_ODE_steps = 5e8; - int maximum_number_of_convergence_failures = 100; - double maximum_ODE_integration_time = 13.8e10; - - /*************************** - * setup of ODE variables * - **************************/ - N_Vector y, y_out, y_abs_tol; - void *cvode_mem; - int flag; - - y = y_out = y_abs_tol = NULL; - cvode_mem = NULL; - - int number_of_ODE_variables = N_bodies*5 + N_binaries*6; // spin vectors + mass + radius for each body + e & h vectors for each binary -// printf("N_ODE %d\n",number_of_ODE_variables); - -// data->number_of_ODE_variables = number_of_ODE_variables; - y = N_VNew_Serial(number_of_ODE_variables); - if (check_flag((void *)y, "N_VNew_Serial", 0)) return 1; - y_out = N_VNew_Serial(number_of_ODE_variables); - if (check_flag((void *)y_out, "N_VNew_Serial", 0)) return 1; - y_abs_tol = N_VNew_Serial(number_of_ODE_variables); - if (check_flag((void *)y_abs_tol, "N_VNew_Serial", 0)) return 1; - - set_initial_ODE_variables(particlesMap, y, y_abs_tol,abs_tol_spin_vec,abs_tol_e_vec,abs_tol_h_vec); - - /*************************** - * setup of ODE integrator * - **************************/ - - /* use Backward Differentiation Formulas (BDF) - scheme in conjunction with Newton iteration -- - these choices are recommended for stiff ODEs - in the CVODE manual - */ - - cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); - if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return 1; - - /* essential initializations */ - flag = CVodeInit(cvode_mem, compute_y_dot, start_time, y); - if (check_flag(&flag, "CVodeInit", 1)) return 1; - - flag = CVodeSetUserData(cvode_mem, data); - if (check_flag(&flag, "CVodeSetUsetData", 1)) return 1; - - flag = CVodeSVtolerances(cvode_mem, relative_tolerance, y_abs_tol); - if (check_flag(&flag, "CVodeSVtolerances", 1)) return 1; - - flag = CVDense(cvode_mem, number_of_ODE_variables); - if (check_flag(&flag, "CVDense", 1)) return 1; - - flag = CVodeSetInitStep(cvode_mem, initial_ODE_timestep); - if (check_flag(&flag, "CVodeSetInitStep", 1)) return 1; - - /* optional initializations */ -// flag = CVodeSetErrHandlerFn(cvode_mem, ehfun, eh_data); // error handling function -// if (check_flag(&flag, "CVodeSetErrHandlerFn", 1)) return; - - flag = CVodeSetMaxNumSteps(cvode_mem, maximum_number_of_internal_ODE_steps); - if (check_flag(&flag, "CVodeSetMaxNumSteps", 1)) return 1; - -// flag = CVodeSetMinStep(cvode_mem, 0.1); // minimum step size -// if (check_flag(&flag, "CVodeSetMinStep", 1)) return 1; - - flag = CVodeSetMaxHnilWarns(cvode_mem, 1); - if (check_flag(&flag, "CVodeSetMaxHnilWarns", 1)) return 1; - -// flag = CVodeSetStopTime(cvode_mem, MAXTIME); // maximum time -// if (check_flag(&flag, "CVodeSetStopTime", 1)) return 1; - - flag = CVodeSetMaxConvFails(cvode_mem, maximum_number_of_convergence_failures); - if (check_flag(&flag, "CVodeSetMaxConvFails", 1)) return 1; - - /* initialization of root finding */ - int roots_found[N_root_finding]; - flag = CVodeRootInit(cvode_mem, N_root_finding, root_finding_functions); - if (check_flag(&flag, "CVodeRootInit", 1)) return 1; - - - /*************************** - * ODE integration * - **************************/ - - double user_end_time = start_time + time_step; - double integrator_end_time; - - flag = CVode(cvode_mem, user_end_time, y_out, &integrator_end_time, CV_NORMAL); - - if (check_for_initial_roots(particlesMap) > 0) - { - flag = CV_ROOT_RETURN; - } - - if (flag == CV_SUCCESS) - { - *output_flag = CV_SUCCESS; - *error_code = 0; - *output_time = integrator_end_time; - } - else if (flag == CV_ROOT_RETURN) // a root was found during the integration - { - CVodeGetRootInfo(cvode_mem,roots_found); - read_root_finding_data(particlesMap,roots_found); - *output_flag = CV_ROOT_RETURN; - *output_time = integrator_end_time; - } - else if (flag == CV_WARNING) // a warning has occurred during the integration - { - *output_flag = 99; - *error_code = flag; - } - else // an error has occurred during the integration - { - *output_flag = flag; - *error_code = flag; - } - - /*************************** - * y_out -> particlesMap * - * ************************/ - - extract_final_ODE_variables(particlesMap,y_out); - update_position_vectors_external_particles(particlesMap,external_particlesMap,integrator_end_time); - - *hamiltonian = data->hamiltonian; - - N_VDestroy_Serial(y); - N_VDestroy_Serial(y_out); - N_VDestroy_Serial(y_abs_tol); - CVodeFree(&cvode_mem); - - return 0; - - -} - - -/* function to check ODE solver-related function return values */ -static int check_flag(void *flagvalue, char *funcname, int opt) -{ - int *errflag; - - /* Check if SUNDIALS function returned NULL pointer - no memory allocated */ - if (opt == 0 && flagvalue == NULL) { - fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n", - funcname); - return(1); } - - /* Check if flag < 0 */ - else if (opt == 1) { - errflag = (int *) flagvalue; - if (*errflag < 0) { - fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", - funcname, *errflag); - return(1); }} - - /* Check if function returned NULL pointer - no memory allocated */ - else if (opt == 2 && flagvalue == NULL) { - fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", - funcname); - return(1); } - - return 0; -} diff --git a/src/amuse/community/secularmultiple/src/evolve.h b/src/amuse/community/secularmultiple/src/evolve.h deleted file mode 100644 index cc79e28c49..0000000000 --- a/src/amuse/community/secularmultiple/src/evolve.h +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include - -#include "types.h" -#include "../interface.h" - -#include "cvode/cvode.h" /* prototypes for CVODE fcts., consts. */ -#include "cvode/nvector_serial.h" /* serial N_Vector types, fcts., macros */ -#include "cvode/cvode_dense.h" /* prototype for CVDense */ -#include "cvode/sundials_dense.h" /* definitions DlsMat DENSE_ELEM */ -#include "cvode/sundials_types.h" /* definition of type realtype */ - -#include "structure.h" -#include "ODE_system.h" -#include "root_finding.h" -#include "newtonian.h" -#include "postnewtonian.h" -#include "tides.h" -#include "external.h" - - -int evolve(ParticlesMap *particlesMap, External_ParticlesMap *external_particlesMap, double start_time, double time_step, double *output_time, double *hamiltonian, int *output_flag, int *error_code); -static int check_flag(void *flagvalue, char *funcname, int opt); diff --git a/src/amuse/community/secularmultiple/src/external.cpp b/src/amuse/community/secularmultiple/src/external.cpp deleted file mode 100644 index 0ea389ba31..0000000000 --- a/src/amuse/community/secularmultiple/src/external.cpp +++ /dev/null @@ -1,966 +0,0 @@ -/* -*/ - -#include "types.h" -#include "external.h" -#include "../interface.h" /* for parameters */ -#include "structure.h" /* for determine_binary_parents_and_levels */ -#include - - -void apply_user_specified_instantaneous_perturbation(ParticlesMap *particlesMap) -{ - set_positions_and_velocities(particlesMap); - update_masses_positions_and_velocities_of_all_bodies(particlesMap); - update_masses_positions_and_velocities_of_all_binaries(particlesMap); - update_orbital_vectors_in_binaries_from_positions_and_velocities(particlesMap); -} - - -void set_positions_and_velocities(ParticlesMap *particlesMap) -{ - /* Compute and set the positions and velocities of all bodies */ - /* By default, sample orbital phases randomly - * if particle.sample_orbital_phases_randomly == False: look for particle.true_anomaly */ - - //determine_binary_parents_and_levels(particlesMap,&N_bodies,&N_binaries,&N_root_finding); - - set_binary_masses_from_body_masses(particlesMap); - - double true_anomaly; - - int seed = orbital_phases_random_seed; - - int index = 0; - int i; - - double r[3],v[3],r_parent[3],v_parent[3],r_child1[3],v_child1[3],r_child2[3],v_child2[3]; - double parent_mass,child1_mass,child2_mass; - double e_vec[3],h_vec[3]; - double e; - - /*/ Go from the top of the system (level=0) downwards */ - - ParticlesMapIterator it; - int highest_level = (*particlesMap)[0]->highest_level; - int level = 0; - while (level < highest_level) - { - for (it = particlesMap->begin(); it != particlesMap->end(); it++) - { - Particle *parent = (*it).second; - if ((parent->is_binary == 1) && (parent->level == level)) - { - Particle *child1 = (*particlesMap)[parent->child1]; - Particle *child2 = (*particlesMap)[parent->child2]; - - child1_mass = child1->mass; - child2_mass = child2->mass; - parent_mass = parent->mass; - - get_e_and_h_vectors_from_particle(parent,e_vec,h_vec); - - if (parent->sample_orbital_phases_randomly == 0) - { - true_anomaly = parent->true_anomaly; - } - else - { - e = norm3(e_vec); - true_anomaly = sample_random_true_anomaly(e,seed+index); - //printf("parent->sample_orbital_phases_randomly %d %g \n",parent->sample_orbital_phases_randomly,true_anomaly); - } - - - from_orbital_vectors_to_cartesian( - child1_mass,child2_mass, - e_vec,h_vec, - true_anomaly, - r,v); - - - if (parent->level == 0) - { - /* without loss of generality, set the initial CM of the system to the origin */ - for (i=0; i<3; i++) - { - r_parent[i] = 0.0; - v_parent[i] = 0.0; - } - } - else - { - get_position_and_velocity_vectors_from_particle(parent,r_parent,v_parent); - } - - for (i=0; i<3; i++) - { - r_child1[i] = r_parent[i] + (child2_mass/parent_mass)*r[i]; - v_child1[i] = v_parent[i] + (child2_mass/parent_mass)*v[i]; - - r_child2[i] = r_parent[i] - (child1_mass/parent_mass)*r[i]; - v_child2[i] = v_parent[i] - (child1_mass/parent_mass)*v[i]; - } - set_position_and_velocity_vectors_in_particle(child1,r_child1,v_child1); - set_position_and_velocity_vectors_in_particle(child2,r_child2,v_child2); - - parent->true_anomaly = true_anomaly; - } - } - level++; - } -} - - -void update_masses_positions_and_velocities_of_all_bodies(ParticlesMap *particlesMap) -{ - /* Update the masses, positions and velocities of the bodies */ - - ParticlesMapIterator it; - for (it = particlesMap->begin(); it != particlesMap->end(); it++) - { - Particle *body = (*it).second; - if (body->is_binary == 0) - { - body->mass += body->instantaneous_perturbation_delta_mass; - body->position_x += body->instantaneous_perturbation_delta_position_x; - body->position_y += body->instantaneous_perturbation_delta_position_y; - body->position_z += body->instantaneous_perturbation_delta_position_z; - - body->velocity_x += body->instantaneous_perturbation_delta_velocity_x; - body->velocity_y += body->instantaneous_perturbation_delta_velocity_y; - body->velocity_z += body->instantaneous_perturbation_delta_velocity_z; - - //printf("test instantaneous_perturbation_delta_mass body %d delta m %g\n",body->index,body->instantaneous_perturbation_delta_mass); - //printf("x %g y %g z %g \n",body->position_x,body->position_y,body->position_z); - //printf("x %g y %g z %g \n",body->instantaneous_perturbation_delta_velocity_x,body->instantaneous_perturbation_delta_velocity_y,body->instantaneous_perturbation_delta_velocity_z); - } - } -} - - - - -void update_masses_positions_and_velocities_of_all_binaries(ParticlesMap *particlesMap) -{ - set_binary_masses_from_body_masses(particlesMap); - - //printf("update_masses_positions_and_velocities_of_all_binaries\n"); - /* set binary positions and velocities -- to ensure this happens correctly, do this from highest level to lowest level */ - - int i; - double child1_mass,child2_mass; - double r[3],v[3]; - double r_child1[3],v_child1[3]; - double r_child2[3],v_child2[3]; - - ParticlesMapIterator it_p; - int highest_level = (*particlesMap)[0]->highest_level; - int level=highest_level; - while (level > -1) - { - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *p = (*it_p).second; - if ((p->is_binary == 1) && (p->level == level)) - { - Particle *child1 = (*particlesMap)[p->child1]; - Particle *child2 = (*particlesMap)[p->child2]; - - get_position_and_velocity_vectors_from_particle(child1,r_child1,v_child1); - get_position_and_velocity_vectors_from_particle(child2,r_child2,v_child2); - - //printf("level %d %d %d\n",p->level,child1->is_binary,child2->is_binary); - - child1_mass = child1->mass; - child2_mass = child2->mass; - - for (i=0; i<3; i++) - { - //r[i] = r_child1[i] - r_child2[i]; - //v[i] = v_child1[i] - v_child2[i]; - r[i] = (r_child1[i]*child1_mass + r_child2[i]*child2_mass)/(child1_mass+child2_mass); - v[i] = (v_child1[i]*child1_mass + v_child2[i]*child2_mass)/(child1_mass+child2_mass); - - //printf("r_child1[i] %g r[i] %g\n",r_child1[i],r[i]); - //printf("r_child2[i] %g r[i] %g\n",r_child2[i],r[i]); - - } - - set_position_and_velocity_vectors_in_particle(p,r,v); - - - -// printf("level %d m %g hl %d\n",level,P_p->mass,highest_level); - } - } - level--; - } -} - - -void update_orbital_vectors_in_binaries_from_positions_and_velocities(ParticlesMap *particlesMap) -{ - //printf("update_orbital_vectors_in_binaries_from_positions_and_velocities\n"); - - int index = 0; - int i; - - double r[3],v[3],r_child1[3],v_child1[3],r_child2[3],v_child2[3]; - double child1_mass,child2_mass; - double e_vec[3],h_vec[3]; - - /*/ Go from the top of the system (level=0) downwards */ - - ParticlesMapIterator it; - int highest_level = (*particlesMap)[0]->highest_level; - int level = 0; - while (level < highest_level) - { - for (it = particlesMap->begin(); it != particlesMap->end(); it++) - { - Particle *parent = (*it).second; - if ((parent->is_binary == 1) && (parent->level == level)) - { - Particle *child1 = (*particlesMap)[parent->child1]; - Particle *child2 = (*particlesMap)[parent->child2]; - - child1_mass = child1->mass; - child2_mass = child2->mass; - - //get_position_and_velocity_vectors_from_particle(parent,r,v); - get_position_and_velocity_vectors_from_particle(child1,r_child1,v_child1); - get_position_and_velocity_vectors_from_particle(child2,r_child2,v_child2); - //printf("level %d\n",parent->level); - for (i=0; i<3; i++) - { - r[i] = r_child1[i] - r_child2[i]; - v[i] = v_child1[i] - v_child2[i]; - //printf("r_child1[i] %g r[i] %g %g\n",r_child1[i],r[i],parent->position_x); - //printf("r_child2[i] %g r[i] %g\n",r_child2[i],r[i]); - } - - from_cartesian_to_orbital_vectors( - child1_mass,child2_mass, - r,v, - e_vec,h_vec); - - set_e_and_h_vectors_in_particle(parent,e_vec,h_vec); - } - } - level++; - } -} - - - - -void compute_position_vectors_external_particles(ParticlesMap *particlesMap, External_Particle *perturber, double time, double *r_per, double r_per_vec[3]) -{ - - double dt = time - perturber->t_ref; - int perturber_path = perturber->path; - - if (perturber_path == 0) /* straight line */ - { - double r0_per_vec[3] = {perturber->r0_vec_x,perturber->r0_vec_y,perturber->r0_vec_z}; - double rdot_per_vec[3] = {perturber->rdot_vec_x,perturber->rdot_vec_y,perturber->rdot_vec_z}; - - for (int i=0; i<3; i++) - { - r_per_vec[i] = r0_per_vec[i] + rdot_per_vec[i]*dt; - } - - *r_per = norm3(r_per_vec); - } - else if (perturber_path == 1) /* hyperbolic orbit */ - { - double e_f = perturber->eccentricity; - double rp_f = perturber->periapse_distance; - double abs_a_f = rp_f/(e_f-1.0); - double total_internal_system_mass = (*particlesMap)[0]->total_system_mass; - double n_f = sqrt(CONST_G*total_internal_system_mass/(abs_a_f*abs_a_f*abs_a_f)); - double mean_anomaly = n_f*dt; - double cos_true_anomaly,sin_true_anomaly; - compute_true_anomaly_from_mean_anomaly_hyperbolic_orbit(mean_anomaly,e_f,&cos_true_anomaly,&sin_true_anomaly); - - *r_per = rp_f*(1.0 + e_f)/(1.0 + e_f*cos_true_anomaly); - - double e_f_hat_vec[3] = {perturber->e_hat_vec_x,perturber->e_hat_vec_y,perturber->e_hat_vec_z}; - double h_f_hat_vec[3] = {perturber->h_hat_vec_x,perturber->h_hat_vec_y,perturber->h_hat_vec_z}; - double q_f_hat_vec[3]; - cross3(h_f_hat_vec,e_f_hat_vec,q_f_hat_vec); - - //printf("evolve %g %g %g %g\n",r_per,mean_anomaly,cos_true_anomaly,total_internal_system_mass); - for (int i=0; i<3; i++) - { - r_per_vec[i] = *r_per*(cos_true_anomaly*e_f_hat_vec[i] + sin_true_anomaly*q_f_hat_vec[i]); - //r_per_vec[i] = r_per*(sin_true_anomaly*r_per_e_hat_vec[i] - cos_true_anomaly*r_per_q_hat_vec[i]); - } - } -} - -void update_position_vectors_external_particles(ParticlesMap *particlesMap, External_ParticlesMap *external_particlesMap, double time) -{ - External_ParticlesMapIterator it_f; - - double dt; /* time relative to periapse */ - double r_per_vec[3]; - double r_per; - - for (it_f = external_particlesMap->begin(); it_f != external_particlesMap->end(); it_f++) - { - External_Particle *perturber = (*it_f).second; - compute_position_vectors_external_particles(particlesMap, perturber, time, &r_per, r_per_vec); - - perturber->r_vec_x = r_per_vec[0]; - perturber->r_vec_y = r_per_vec[1]; - perturber->r_vec_z = r_per_vec[2]; - } -} - - -double compute_EOM_binary_pairs_external_perturbation(ParticlesMap *particlesMap, External_ParticlesMap *external_particlesMap, int binary_index, int perturber_index, double time, bool compute_hamiltonian_only) -{ - /* last checked 16-09-16 */ - - //printf("compute_EOM_binary_pairs_external_perturbation perturber_index %d\n",perturber_index); - - /* stop if no pairwise terms are to be computed */ - if ((include_quadrupole_order_terms == false) && (include_octupole_order_binary_pair_terms == false) && (include_hexadecupole_order_binary_pair_terms == false) && (include_dotriacontupole_order_binary_pair_terms == false) ) - { - return 0.0; - } - - - Particle *binary = (*particlesMap)[binary_index]; - External_Particle *perturber = (*external_particlesMap)[perturber_index]; - - -// printf("compute_EOM_binary_pairs inner_binary_index %d outer_binary_index %d connecting_child_in_outer_binary %d P_sibling %d sibling_mass %g\n",inner_binary_index,outer_binary_index,connecting_child_in_outer_binary,P_sibling->index,P_sibling->mass); - - double e = binary->e; - double e_p2 = binary->e_p2; - - double *e_vec = binary->e_vec; - double *h_vec = binary->h_vec; - - double *e_vec_unit = binary->e_vec_unit; - double *h_vec_unit = binary->h_vec_unit; - - double h = binary->h; - double j = binary->j; - - double j_vec[3]; - for (int i=0; i<3; i++) - { - j_vec[i] = j*h_vec_unit[i]; - } - - double a = binary->a; - - double t_per_ref = perturber->t_ref; - double dt = time - t_per_ref; - double M_per = perturber->mass; - - //printf("test t %.15g %.15g %.15g\n",t_per_ref,time,dt); - - //printf("test %g %g %g %g %g %g %g %g\n",perturber->r0_vec_x,perturber->r0_vec_y,perturber->r0_vec_z,perturber->rdot_vec_x,perturber->rdot_vec_y,perturber->rdot_vec_z,perturber->t_ref,perturber->mass); - - double r_per_vec[3]; - double r_per; - - compute_position_vectors_external_particles(particlesMap,perturber,time,&r_per,r_per_vec); - - double r_per_p2 = r_per*r_per; - double r_per_pm1 = 1.0/r_per; - - //printf("test r %.15g %.15g %.15g %.15g\n",r_per,r_per_vec[0],r_per_vec[1],r_per_vec[2]); - double e_vec_dot_r_per_vec = dot3(e_vec,r_per_vec); - double j_vec_dot_r_per_vec = dot3(j_vec,r_per_vec); - - double m1 = binary->child1_mass; - double m2 = binary->child2_mass; - -// printf("m1 %g m2 %g m3 %g\n",m1,m2,m3); -// printf("a_in %g a_out %g\n",a_in,a_out); - - double m1_plus_m2 = binary->child1_mass_plus_child2_mass; - double m1_minus_m2 = binary->child1_mass_minus_child2_mass; - double m1_times_m2 = binary->child1_mass_times_child2_mass; - - int n,m,i1,i2; /* n: order of expansion, starts at n = 2; 0 <= m <= n; i1 + i2 <= m */ - double constant_Hamiltonian_factor = (m1_times_m2/m1_plus_m2)*(CONST_G*M_per/r_per); /* constant factor in Hamiltonian*/ - - double M_bin_pnm1; /* M_bin to power n - 1 */ - double M_bin_child1_pnm1; /* M_bin_child1 to power n - 1 */ - double M_bin_child2_pnm1; /* M_bin_child2 to power n - 1 */ - double minusone_pnp1; /* minus one to power n + 1 */ - double r_per_pmn; /* r_per to power 1/n */ - double a_pn; /* binary a to power n */ - - double mass_factor_children = 0.0; - double binary_pair_hamiltonian = 0.0; - double hamiltonian_factor = 0.0; - double A_n_m = 0.0; - double B_n_m_i1_i2 = 0.0; - double dB_n_m_i1_i2_de = 0.0; /* derivative of B-function w.r.t. e */ - - double e_p_array_even[HIGHEST_POWER_ECCP2_IN_B_TABLE]; - double e_p_array_odd[HIGHEST_POWER_ECCP2_IN_B_TABLE]; - e_p_array_even[0] = 1.0; - e_p_array_odd[1] = e; - int index_B_eccp2; - for (index_B_eccp2=1; index_B_eccp2<= HIGHEST_POWER_ECCP2_IN_B_TABLE; index_B_eccp2++) - { - e_p_array_even[index_B_eccp2] = e_p_array_even[index_B_eccp2-1]*e_p2; - - if (index_B_eccp2>1) - { - e_p_array_odd[index_B_eccp2] = e_p_array_odd[index_B_eccp2-1]*e_p2; - } - } - - double grad_e_vec_H[3],grad_j_vec_H[3]; - for (int i=0; i<3; i++) - { - grad_e_vec_H[i] = grad_j_vec_H[i] = 0.0; - } - - int index_A,index_B; - int n_lookup,m_lookup; - int n_old = 2; - - bool continue_to_B_table; - double B_lookup = 0.0; - double r_per_pow_mi1mi2,e_vec_dot_r_per_vec_pi1,j_vec_dot_r_per_vec_pi2,e_vec_dot_r_per_vec_pi1m1,j_vec_dot_r_per_vec_pi2m1; - for (index_B=0; index_B0) - { - dB_n_m_i1_i2_de += 2.0*index_B_eccp2*B_lookup*e_p_array_odd[index_B_eccp2]; - } - } - //printf("test... n %d m %d i1 %d i2 %d e %g B %g \n",n,m,i1,i2,e,B_n_m_i1_i2); - //printf("test D... n %d m %d i1 %d i2 %d e %g B %g \n",n,m,i1,i2,e,dB_n_m_i1_i2_de); - - M_bin_pnm1 = pow(m1_plus_m2,n-1.0); - M_bin_child1_pnm1 = pow(m1,n-1.0); - M_bin_child2_pnm1 = pow(m2,n-1.0); - a_pn = pow(a,n); - r_per_pmn = pow(r_per_pm1,n); - minusone_pnp1 = pow(-1.0,n+1.0); - - //printf("test2 %d %d %d %d %g %g %g\n",n,m,i1,i2,A_n_m,B_n_m_i1_i2,dB_n_m_i1_i2_de); - - /* compute the Hamiltonian */ - r_per_pow_mi1mi2 = pow(r_per,-i1-i2); - e_vec_dot_r_per_vec_pi1 = pow(e_vec_dot_r_per_vec,i1); - j_vec_dot_r_per_vec_pi2 = pow(j_vec_dot_r_per_vec,i2); - - e_vec_dot_r_per_vec_pi1m1 = pow(e_vec_dot_r_per_vec,i1-1.0); - j_vec_dot_r_per_vec_pi2m1 = pow(j_vec_dot_r_per_vec,i2-1.0); - - mass_factor_children = fabs(M_bin_child1_pnm1 - minusone_pnp1*M_bin_child2_pnm1); - hamiltonian_factor = minusone_pnp1*constant_Hamiltonian_factor*(mass_factor_children/M_bin_pnm1)*a_pn*r_per_pmn*A_n_m*r_per_pow_mi1mi2; - - binary_pair_hamiltonian += hamiltonian_factor*e_vec_dot_r_per_vec_pi1*j_vec_dot_r_per_vec_pi2*B_n_m_i1_i2; - - /* compute EOM */ - if (compute_hamiltonian_only == false) - { - for (int i=0; i<3; i++) - { - grad_e_vec_H[i] += hamiltonian_factor*j_vec_dot_r_per_vec_pi2*( double(i1)*B_n_m_i1_i2*e_vec_dot_r_per_vec_pi1m1*r_per_vec[i] + e_vec_dot_r_per_vec_pi1*dB_n_m_i1_i2_de*e_vec_unit[i] ); - grad_j_vec_H[i] += hamiltonian_factor*e_vec_dot_r_per_vec_pi1*B_n_m_i1_i2*double(i2)*j_vec_dot_r_per_vec_pi2m1*r_per_vec[i]; - } - } - } - - - double j_vec_cross_grad_j_vec_H[3],j_vec_cross_grad_e_vec_H[3]; - double e_vec_cross_grad_e_vec_H[3],e_vec_cross_grad_j_vec_H[3]; - - cross3(j_vec, grad_j_vec_H, j_vec_cross_grad_j_vec_H); - cross3(j_vec, grad_e_vec_H, j_vec_cross_grad_e_vec_H); - cross3(e_vec, grad_e_vec_H, e_vec_cross_grad_e_vec_H); - cross3(e_vec, grad_j_vec_H, e_vec_cross_grad_j_vec_H); - - double Lambda = h/j; - for (int i=0; i<3; i++) - { - binary->de_vec_dt[i] += (-1.0/(Lambda))*( e_vec_cross_grad_j_vec_H[i] \ - + j_vec_cross_grad_e_vec_H[i] ); - binary->dh_vec_dt[i] += -1.0*( j_vec_cross_grad_j_vec_H[i] \ - + e_vec_cross_grad_e_vec_H[i] ); - } - //printf("test dedt %g\n",dot3(binary->e_vec_unit,binary->de_vec_dt)); - -} - -void compute_true_anomaly_from_mean_anomaly_hyperbolic_orbit(double mean_anomaly, double eccentricity,double *cos_true_anomaly,double *sin_true_anomaly) -{ - double eccentric_anomaly; - - double fabs_mean_anomaly = fabs(mean_anomaly); - double sign_mean_anomaly; - - sign_mean_anomaly = copysign( 1.0, mean_anomaly); - - double eccentric_anomaly_next; - - if (fabs_mean_anomaly < 3.0*eccentricity) - { - double s1 = fabs_mean_anomaly/(eccentricity-1.0); - double s2 = pow( 6.0*fabs_mean_anomaly, 1.0/3.0); - eccentric_anomaly_next = sign_mean_anomaly*min(s1,s2); - } - else - { - eccentric_anomaly_next = sign_mean_anomaly*log(1.0 + 2.0*fabs_mean_anomaly/eccentricity); - } - - double epsilon = 1e-10; - double error = 2.0*epsilon; /* to start: anything larger than epsilon */ - int j = 0; - while (error > epsilon) - { - j += 1; - eccentric_anomaly = eccentric_anomaly_next; - eccentric_anomaly_next = eccentric_anomaly + (eccentric_anomaly - eccentricity*sinh(eccentric_anomaly) + mean_anomaly)/(eccentricity*cosh(eccentric_anomaly) - 1.0); - error = fabs(eccentric_anomaly_next - eccentric_anomaly); - - if (j > 15) - { - //printf("test %d %g %g %g %g %g\n",j,mean_anomaly,eccentric_anomaly,eccentric_anomaly_next,error,epsilon); - break; - } - } - - double tau = sqrt( (eccentricity+1.0)/(eccentricity-1.0) )*tanh(0.5*eccentric_anomaly); /* tan(true_anomaly/2) */ - double tau_sq = tau*tau; - double temp = 1.0/(1.0 + tau_sq); - - *cos_true_anomaly = (1.0 - tau_sq)*temp; - *sin_true_anomaly = 2.0*tau*temp; - - //printf("test %g %g\n",mean_anomaly,eccentric_anomaly); -} - - -int apply_external_perturbation_assuming_integrated_orbits(ParticlesMap *particlesMap, External_ParticlesMap *external_particlesMap) -{ - ParticlesMapIterator it_p; - External_ParticlesMapIterator it_f; - - /* make sure that total_system_mass is updated */ - int N_particles = particlesMap->size(); - int N_bodies, N_binaries; - int N_root_finding; - - determine_binary_parents_and_levels(particlesMap,&N_bodies,&N_binaries,&N_root_finding); - set_binary_masses_from_body_masses(particlesMap); - - - /* compute and apply perturbations */ - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *p = (*it_p).second; - - if (p->is_binary == 1) - { - - /* set e_vec & h_vec (for time integration done in set_initial_ODE_variables, but not in this case */ - p->e_vec[0] = p->e_vec_x; - p->e_vec[1] = p->e_vec_y; - p->e_vec[2] = p->e_vec_z; - p->h_vec[0] = p->h_vec_x; - p->h_vec[1] = p->h_vec_y; - p->h_vec[2] = p->h_vec_z; - p->set_ODE_quantities(0.0); /* argument is delta time, which is not needed/used in this case */ - for (it_f = external_particlesMap->begin(); it_f != external_particlesMap->end(); it_f++) - { - External_Particle *f = (*it_f).second; - if (f->mode == 1) - { - apply_external_perturbation_assuming_integrated_orbits_binary_pair(particlesMap,external_particlesMap,p->index,f->index); - } - } - } - } - - return 0; -} - -void apply_external_perturbation_assuming_integrated_orbits_binary_pair(ParticlesMap *particlesMap, External_ParticlesMap *external_particlesMap, int binary_index, int perturber_index) -{ - - /* stop if no pairwise terms are to be computed */ - if ((include_quadrupole_order_terms == false) && (include_octupole_order_binary_pair_terms == false) && (include_hexadecupole_order_binary_pair_terms == false) && (include_dotriacontupole_order_binary_pair_terms == false) ) - { - return; - } - - Particle *binary = (*particlesMap)[binary_index]; - External_Particle *perturber = (*external_particlesMap)[perturber_index]; - - /* unsubscripted elements/vectors refer to the binary */ - double e = binary->e; - double e_p2 = binary->e_p2; - - double *e_vec = binary->e_vec; - double *h_vec = binary->h_vec; - - double *e_vec_unit = binary->e_vec_unit; - double *h_vec_unit = binary->h_vec_unit; - - double h = binary->h; - double j = binary->j; - double a = binary->a; - - double j_vec[3]; - for (int i=0; i<3; i++) - { - j_vec[i] = j*h_vec_unit[i]; - } - - double M_per = perturber->mass; - - double grad_e_vec_H[3],grad_j_vec_H[3]; - for (int i=0; i<3; i++) - { - grad_e_vec_H[i] = grad_j_vec_H[i] = 0.0; - } - - int perturber_path = perturber->path; - if (perturber_path == 0) /* straight line */ - { - - /* not yet implemented */ - exit(0); - } - else if (perturber_path == 1) /* hyperbolic orbit */ - { - - double e_f = perturber->eccentricity; - double q_f = perturber->periapse_distance; - double abs_a_f = q_f/(e_f-1.0); - double total_internal_system_mass = binary->total_system_mass; /* make sure this is up to date */ - double n_f = sqrt(CONST_G*total_internal_system_mass/(abs_a_f*abs_a_f*abs_a_f)); - - double e_f_hat_vec[3] = {perturber->e_hat_vec_x,perturber->e_hat_vec_y,perturber->e_hat_vec_z}; - double j_f_hat_vec[3] = {perturber->h_hat_vec_x,perturber->h_hat_vec_y,perturber->h_hat_vec_z}; /* note: j_hat and h_hat are the same */ - - double e_f_p2 = e_f*e_f; - double e_f_p4 = e_f_p2*e_f_p2; - double one_div_e_f_p1 = 1.0/e_f; - double one_div_e_f_p2 = one_div_e_f_p1*one_div_e_f_p1; - double one_div_e_f_p3 = one_div_e_f_p1*one_div_e_f_p2; - double e_f_p2_minus_one = e_f_p2 - 1.0; - double sqrt_e_f_p2_minus_one = sqrt(e_f_p2_minus_one); - double e_f_p2_minus_one_p3div2 = e_f_p2_minus_one*sqrt_e_f_p2_minus_one; - double asec_minus_e_f = acos(-1.0/e_f); /* asec(x) = acos(1/x) */ - - double one_plus_e_f = 1.0 + e_f; - double one_plus_e_f_pm1 = 1.0/one_plus_e_f; - double one_plus_e_f_pmn; - - - double e_vec_dot_e_f_hat_vec = dot3(e_vec,e_f_hat_vec); - double j_vec_dot_j_f_hat_vec = dot3(j_vec,j_f_hat_vec); - double e_vec_dot_j_f_hat_vec = dot3(e_vec,j_f_hat_vec); - double j_vec_dot_e_f_hat_vec = dot3(j_vec,e_f_hat_vec); - - double e_vec_dot_e_f_hat_vec_pl1,e_vec_dot_e_f_hat_vec_pl1m1; - double j_vec_dot_j_f_hat_vec_pl2,j_vec_dot_j_f_hat_vec_pl2m1; - double e_vec_dot_j_f_hat_vec_pl3,e_vec_dot_j_f_hat_vec_pl3m1; - double j_vec_dot_e_f_hat_vec_pl4,j_vec_dot_e_f_hat_vec_pl4m1; - - double m1 = binary->child1_mass; - double m2 = binary->child2_mass; - - // printf("m1 %g m2 %g m3 %g\n",m1,m2,m3); - // printf("a_in %g a_out %g\n",a_in,a_out); - - double m1_plus_m2 = binary->child1_mass_plus_child2_mass; - double m1_minus_m2 = binary->child1_mass_minus_child2_mass; - double m1_times_m2 = binary->child1_mass_times_child2_mass; - - int n,m,i1,i2,l1,l2,l3,l4; /* n: order of expansion, starts at n = 2; 0 <= m <= n; i1 + i2 <= m */ - double constant_integrated_hamiltonian_factor = (m1_times_m2/m1_plus_m2)*(CONST_G*M_per/(q_f*one_plus_e_f))*(1.0/n_f)*e_f_p2_minus_one_p3div2; /* constant factor in Hamiltonian*/ - - - double M_bin_pnm1; /* M_bin to power n - 1 */ - double M_bin_child1_pnm1; /* M_bin_child1 to power n - 1 */ - double M_bin_child2_pnm1; /* M_bin_child2 to power n - 1 */ - double minusone_pnp1; /* minus one to power n + 1 */ - double a_pn; /* binary a to power n */ - double q_f_pm1 = 1.0/q_f; - double q_f_pmn; - - double mass_factor_children = 0.0; - double binary_pair_integrated_hamiltonian = 0.0; - double integrated_hamiltonian_factor = 0.0; - double A_n_m = 0.0; - double B_n_m_i1_i2 = 0.0; - double dB_n_m_i1_i2_de = 0.0; /* derivative of B function w.r.t. e */ - int D_n_i1_i2_l1_l2_l3_l4_function_index; - double D_n_i1_i2_l1_l2_l3_l4 = 0.0; - double dD_n_i1_i2_l1_l2_l3_l4_de = 0.0; /* derivative of D function w.r.t. e */ - - double e_p_array_even[HIGHEST_POWER_ECCP2_IN_B_TABLE+1]; - double e_p_array_odd[HIGHEST_POWER_ECCP2_IN_B_TABLE+1]; - e_p_array_even[0] = 1.0; - e_p_array_odd[1] = e; - int index_B_eccp2; - for (index_B_eccp2=1; index_B_eccp2 <= HIGHEST_POWER_ECCP2_IN_B_TABLE; index_B_eccp2++) - { - - e_p_array_even[index_B_eccp2] = e_p_array_even[index_B_eccp2-1]*e_p2; - - if (index_B_eccp2>1) - { - e_p_array_odd[index_B_eccp2] = e_p_array_odd[index_B_eccp2-1]*e_p2; - } - } - - int index_A,index_B,index_D; - int n_lookup,m_lookup,i1_lookup,i2_lookup; - - bool continue_after_A_table; - double B_lookup = 0.0; - for (index_B=0; index_B0) - { - dB_n_m_i1_i2_de += 2.0*index_B_eccp2*B_lookup*e_p_array_odd[index_B_eccp2]; - } - } - - /* compute quantities depending on n */ - minusone_pnp1 = pow(-1.0,n+1.0); - M_bin_child1_pnm1 = pow(m1,n-1.0); - M_bin_child2_pnm1 = pow(m2,n-1.0); - M_bin_pnm1 = pow(m1_plus_m2,n-1.0); - a_pn = pow(a,n); - q_f_pmn = pow(q_f_pm1,n); - one_plus_e_f_pmn = pow(one_plus_e_f_pm1,n); - - mass_factor_children = fabs(M_bin_child1_pnm1 - minusone_pnp1*M_bin_child2_pnm1); - integrated_hamiltonian_factor = minusone_pnp1*constant_integrated_hamiltonian_factor*(mass_factor_children/M_bin_pnm1)*a_pn*q_f_pmn*one_plus_e_f_pmn*A_n_m; - - /* construct D function from table */ - for (index_D=0; index_De_vec_x = e_vec[0]; - binary->e_vec_y = e_vec[1]; - binary->e_vec_z = e_vec[2]; - binary->h_vec_x = h_vec[0]; - binary->h_vec_y = h_vec[1]; - binary->h_vec_z = h_vec[2]; -} - -double retrieve_D_function(int function_index, double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - double result = 0.0; - switch (function_index) - { - case 1: result = D_TABLE_FUNC1(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 2: result = D_TABLE_FUNC2(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 3: result = D_TABLE_FUNC3(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 4: result = D_TABLE_FUNC4(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 5: result = D_TABLE_FUNC5(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 6: result = D_TABLE_FUNC6(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 7: result = D_TABLE_FUNC7(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 8: result = D_TABLE_FUNC8(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 9: result = D_TABLE_FUNC9(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 10: result = D_TABLE_FUNC10(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 11: result = D_TABLE_FUNC11(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 12: result = D_TABLE_FUNC12(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 13: result = D_TABLE_FUNC13(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 14: result = D_TABLE_FUNC14(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 15: result = D_TABLE_FUNC15(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - } - //printf("function_index %d %g %g %g result %g \n",function_index,ep,ep_p2,ef,result); - return result; -} - -double retrieve_D_function_e_derivative(int function_index, double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - double result = 0.0; - switch (function_index) - { - case 1: result = D_TABLE_FUNC1_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 2: result = D_TABLE_FUNC2_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 3: result = D_TABLE_FUNC3_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 4: result = D_TABLE_FUNC4_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 5: result = D_TABLE_FUNC5_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 6: result = D_TABLE_FUNC6_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 7: result = D_TABLE_FUNC7_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 8: result = D_TABLE_FUNC8_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 9: result = D_TABLE_FUNC9_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 10: result = D_TABLE_FUNC10_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 11: result = D_TABLE_FUNC11_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 12: result = D_TABLE_FUNC12_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 13: result = D_TABLE_FUNC13_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 14: result = D_TABLE_FUNC14_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - case 15: result = D_TABLE_FUNC15_DER(ep,ep_p2,ef,ef_p2,ef_p4,one_div_ef_p1,one_div_ef_p2,one_div_ef_p3,ef_p2_minus_one,sqrt_ef_p2_minus_one,asec_minus_ef); break; - } - return result; -} diff --git a/src/amuse/community/secularmultiple/src/external.h b/src/amuse/community/secularmultiple/src/external.h deleted file mode 100644 index 49d5fe6cd9..0000000000 --- a/src/amuse/community/secularmultiple/src/external.h +++ /dev/null @@ -1,21 +0,0 @@ -#include "types.h" - -void apply_user_specified_instantaneous_perturbation(ParticlesMap *particlesMap); -void set_positions_and_velocities(ParticlesMap *particlesMap); -void update_masses_positions_and_velocities_of_all_bodies(ParticlesMap *particlesMap); -void update_masses_positions_and_velocities_of_all_binaries(ParticlesMap *particlesMap); -void update_orbital_vectors_in_binaries_from_positions_and_velocities(ParticlesMap *particlesMap); - - - -void update_position_vectors_external_particles(ParticlesMap *particlesMap, External_ParticlesMap *external_particlesMap, double time); -void compute_position_vectors_external_particles(ParticlesMap *particlesMap, External_Particle *perturber, double time, double *r_per, double r_per_vec[3]); - -double compute_EOM_binary_pairs_external_perturbation(ParticlesMap *particlesMap, External_ParticlesMap *external_particlesMap, int binary_index, int perturber_index, double time, bool compute_hamiltonian_only); -void compute_true_anomaly_from_mean_anomaly_hyperbolic_orbit(double mean_anomaly, double eccentricity,double *cos_true_anomaly,double *sin_true_anomaly); - -int apply_external_perturbation_assuming_integrated_orbits(ParticlesMap *particlesMap, External_ParticlesMap *external_particlesMap); -void apply_external_perturbation_assuming_integrated_orbits_binary_pair(ParticlesMap *particlesMap, External_ParticlesMap *external_particlesMap, int binary_index, int perturber_index); - -double retrieve_D_function(int function_index, double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef); -double retrieve_D_function_e_derivative(int function_index, double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef); diff --git a/src/amuse/community/secularmultiple/src/newtonian.cpp b/src/amuse/community/secularmultiple/src/newtonian.cpp deleted file mode 100644 index a2c0ef827e..0000000000 --- a/src/amuse/community/secularmultiple/src/newtonian.cpp +++ /dev/null @@ -1,683 +0,0 @@ -/* -*/ - -#include "types.h" -#include "newtonian.h" -#include "../interface.h" /* for parameters */ -#include - -double compute_orbital_period(Particle *particle) -{ - double a = particle->a; - double total_mass = particle->child1_mass_plus_child2_mass; - return 2.0*M_PI*sqrt(a*a*a/(CONST_G*total_mass)); -} - -double compute_EOM_binary_pairs(ParticlesMap *particlesMap, int inner_binary_index, int outer_binary_index, int connecting_child_in_outer_binary, bool compute_hamiltonian_only) -{ - /* last checked 23-06-15 */ - - - /* stop if no triple terms are to be computed for the binary pair */ - if ((include_quadrupole_order_terms == false) && (include_octupole_order_binary_pair_terms == false) && (include_hexadecupole_order_binary_pair_terms == false) && (include_dotriacontupole_order_binary_pair_terms == false) ) - { - return 0.0; - } - - - /********************* - * preamble * - ********************/ - Particle *inner_binary = (*particlesMap)[inner_binary_index]; - Particle *outer_binary = (*particlesMap)[outer_binary_index]; - - Particle *P_child1 = (*particlesMap)[inner_binary->child1]; - Particle *P_child2 = (*particlesMap)[inner_binary->child2]; - Particle *P_sibling; - if (connecting_child_in_outer_binary==1) - { - P_sibling = (*particlesMap)[outer_binary->child2]; - } - else if (connecting_child_in_outer_binary==2) - { - P_sibling = (*particlesMap)[outer_binary->child1]; - } -// printf("compute_EOM_binary_pairs inner_binary_index %d outer_binary_index %d connecting_child_in_outer_binary %d P_sibling %d sibling_mass %g\n",inner_binary_index,outer_binary_index,connecting_child_in_outer_binary,P_sibling->index,P_sibling->mass); - - double e_in = inner_binary->e; - double e_in_p2 = inner_binary->e_p2; - double e_in_p4 = e_in_p2*e_in_p2; - double e_out = outer_binary->e; - double e_out_p2 = outer_binary->e_p2; - - double *e_in_vec = inner_binary->e_vec; - double *e_out_vec = outer_binary->e_vec; - double *h_in_vec = inner_binary->h_vec; - double *h_out_vec = outer_binary->h_vec; - - double *e_in_vec_unit = inner_binary->e_vec_unit; - double *e_out_vec_unit = outer_binary->e_vec_unit; - double *h_in_vec_unit = inner_binary->h_vec_unit; - double *h_out_vec_unit = outer_binary->h_vec_unit; - - double h_in = inner_binary->h; - double h_out = outer_binary->h; - - double j_in = inner_binary->j; - double j_in_p2 = inner_binary->j_p2; - double j_in_p3 = inner_binary->j_p3; - double j_out = outer_binary->j; - double j_out_p2 = outer_binary->j_p2; - double j_out_p3 = outer_binary->j_p3; - double j_out_p4 = outer_binary->j_p4; - double j_out_p5 = outer_binary->j_p5; - double j_out_p6 = j_out*j_out_p5; - double j_out_p7 = j_out*j_out_p6; - double j_out_p8 = j_out*j_out_p7; - double j_out_p9 = j_out*j_out_p8; - double j_out_p10 = j_out*j_out_p9; - double j_out_p11 = j_out*j_out_p10; - double j_out_p13 = j_out_p2*j_out_p11; - - double j_out_p2_inv = 1.0/j_out_p2; - double j_out_p5_inv = 1.0/j_out_p5; - double j_out_p7_inv = 1.0/j_out_p7; - double j_out_p9_inv = 1.0/j_out_p9; - double j_out_p11_inv = 1.0/j_out_p11; - double j_out_p13_inv = 1.0/j_out_p13; - - double j_in_vec[3],j_out_vec[3]; - for (int i=0; i<3; i++) - { - j_in_vec[i] = j_in*h_in_vec_unit[i]; - j_out_vec[i] = j_out*h_out_vec_unit[i]; - } - - double a_in = inner_binary->a; - double a_out = outer_binary->a; - - /* set alpha = +1 */ - double m1 = P_child1->mass; - double m2 = P_child2->mass; - double m3 = P_sibling->mass; -// printf("m1 %g m2 %g m3 %g\n",m1,m2,m3); -// printf("a_in %g a_out %g\n",a_in,a_out); - - double m1_plus_m2 = inner_binary->child1_mass_plus_child2_mass; - double m1_minus_m2 = inner_binary->child1_mass_minus_child2_mass; - double m1_times_m2 = inner_binary->child1_mass_times_child2_mass; - - double A_quad = c_1div8*CONST_G*(a_in*a_in/(a_out*a_out*a_out))*m1_times_m2*m3/m1_plus_m2; - //double A_oct = A_quad*c_15div8*(a_in/a_out)*m1_minus_m2/m1_plus_m2; - double A_oct = A_quad*c_15div8*(a_in/a_out)*fabs(m1_minus_m2)/m1_plus_m2; /* changed 06-08-15 */ - double A_hd = 0.0; - double A_tc = 0.0; - - if (include_quadrupole_order_terms == false) - { - A_quad = 0.0; - } - if (include_octupole_order_binary_pair_terms == false) - { - A_oct = 0.0; - } - if (include_hexadecupole_order_binary_pair_terms == true) - { - A_hd = c_3div1024*CONST_G*(a_in*a_in*a_in*a_in/(a_out*a_out*a_out*a_out*a_out))*(m1_times_m2*m3*(m1*m1 - m1_times_m2 + m2*m2)/(m1_plus_m2*m1_plus_m2*m1_plus_m2)); -// A_hd = c_3div1024*CONST_G*(a_in*a_in*a_in*a_in/(a_out*a_out*a_out*a_out*a_out))*(m1_times_m2*m3*(m1*m1*m1 + m2*m2*m2)/(m1_plus_m2*m1_plus_m2*m1_plus_m2*m1_plus_m2)); - /* the above two expressions are mathematically identical */ -// printf("hd true %g %g %g\n",A_quad,A_oct,A_hd); - } - if (include_dotriacontupole_order_binary_pair_terms == true) - { - A_tc = -c_105div4096*CONST_G*(a_in*a_in*a_in*a_in*a_in/(a_out*a_out*a_out*a_out*a_out*a_out))*(m1_times_m2*m3*fabs(m1_minus_m2)*(m1*m1 + m2*m2)/(m1_plus_m2*m1_plus_m2*m1_plus_m2*m1_plus_m2)); - } - - double Lambda_in = h_in/j_in; - double Lambda_out = h_out/j_out; - - double e_in_vec_dot_e_out_vec = dot3(e_in_vec,e_out_vec); - double j_in_vec_dot_j_out_vec = dot3(j_in_vec,j_out_vec); - double e_in_vec_dot_j_out_vec = dot3(e_in_vec,j_out_vec); - double j_in_vec_dot_e_out_vec = dot3(j_in_vec,e_out_vec); - - double e_in_vec_dot_e_out_vec_p2 = e_in_vec_dot_e_out_vec*e_in_vec_dot_e_out_vec; - double j_in_vec_dot_j_out_vec_p2 = j_in_vec_dot_j_out_vec*j_in_vec_dot_j_out_vec; - double e_in_vec_dot_j_out_vec_p2 = e_in_vec_dot_j_out_vec*e_in_vec_dot_j_out_vec; - double j_in_vec_dot_e_out_vec_p2 = j_in_vec_dot_e_out_vec*j_in_vec_dot_e_out_vec; - - double j_in_vec_dot_j_out_vec_p4 = j_in_vec_dot_j_out_vec_p2*j_in_vec_dot_j_out_vec_p2; - double e_in_vec_dot_j_out_vec_p4 = e_in_vec_dot_j_out_vec_p2*e_in_vec_dot_j_out_vec_p2; - - /* dotriacontupole */ - double e_in_vec_dot_e_out_vec_p3 = e_in_vec_dot_e_out_vec*e_in_vec_dot_e_out_vec_p2; - double j_in_vec_dot_j_out_vec_p3 = j_in_vec_dot_j_out_vec*j_in_vec_dot_j_out_vec_p2; - double e_in_vec_dot_j_out_vec_p3 = e_in_vec_dot_j_out_vec*e_in_vec_dot_j_out_vec_p2; - - - /*************************** - * compute the Hamiltonian * - **************************/ - - double f1 = (1.0-6.0*e_in_p2)*j_out_p2 + 15.0*e_in_vec_dot_j_out_vec_p2 - 3.0*j_in_vec_dot_j_out_vec_p2; - double f2 = (1.0-8.0*e_in_p2)*j_out_p2 + 35.0*e_in_vec_dot_j_out_vec_p2 - 5.0*j_in_vec_dot_j_out_vec_p2; - double f3 = -10.0*e_in_vec_dot_j_out_vec*j_in_vec_dot_e_out_vec*j_in_vec_dot_j_out_vec; - double f4,f5,f6,f7,f8,f9,f10,f11,f12; /* hexadecupole */ - double g,g1,g2,g3,h1,h2,h3,h4,h5; /* dotriacontupole */ - if (include_hexadecupole_order_binary_pair_terms == true) - { - f4 = -6.0 + e_out_p2 + 40.0*e_in_p2*(1.0 + 8.0*e_out_p2) - 20.0*e_in_p4*(8.0+15.0*e_out_p2); - f5 = -2.0*j_out_p2 - e_in_p2*j_out_p2 + 21.0*e_in_vec_dot_j_out_vec_p2; - f6 = (1.0 - 10.0*e_in_p2)*(4.0 + 3.0*e_out_p2); - f7 = 8.0 + 6.0*e_out_p2 + e_in_p2*(6.0 + 29.0*e_out_p2); - f8 = j_out_p2 + 13.0*e_in_p2*j_out_p2 - 7.0*j_in_vec_dot_j_out_vec_p2; - f9 = -2.0 - 3.0*e_out_p2 + 4.0*e_in_p2*(5.0 + 3.0*e_out_p2); - f10 = j_out_p2 - e_in_p2*j_out_p2 + 7.0*e_in_vec_dot_j_out_vec_p2; - f11 = 2.0 + e_out_p2; - f12 = 3.0*f4*j_out_p4 + 420.0*e_in_vec_dot_e_out_vec_p2*j_out_p2*f5 \ - - 5880.0*j_out_p2*e_in_vec_dot_e_out_vec*j_in_vec_dot_e_out_vec*e_in_vec_dot_j_out_vec*j_in_vec_dot_j_out_vec \ - + 5.0*( 28.0*j_out_p2*f6*e_in_vec_dot_j_out_vec_p2 - 6.0*j_out_p2*f7*j_in_vec_dot_j_out_vec_p2 \ - - 12.0*j_out_p2*f8*j_in_vec_dot_e_out_vec_p2 + 98.0*j_out_p2*f9*e_in_vec_dot_j_out_vec_p2 \ - - 441.0*f11*e_in_vec_dot_j_out_vec_p4 + 42.0*f11*f10*j_in_vec_dot_j_out_vec_p2 \ - - 21.0*f11*j_in_vec_dot_j_out_vec_p4); - } - if (include_dotriacontupole_order_binary_pair_terms == true) - { - h1 = (1.0 - 4.0*e_in_p2)*(8.0 + e_out_p2); - h2 = 8.0 + 3.0*e_out_p2; - h3 = -8.0 + e_out_p2 - 4.0*e_in_p4*(80.0 + 179.0*e_out_p2) + e_in_p2*(64.0 + 748.0*e_out_p2); - h4 = -8.0 - 19.0*e_out_p2 + 6.0*e_in_p2*(16.0 + 5.0*e_out_p2); - h5 = 8.0 + e_out_p2 - 2.0*e_in_p2*(16.0 + 29.0*e_out_p2); - - g1 = (-26.0 + 15.0*e_in_p2)*j_out_p2 + 18.0*j_in_vec_dot_j_out_vec_p2 + 99.0*e_in_vec_dot_j_out_vec_p2; - g2 = h1*j_out_p2 + 9.0*h2*e_in_vec_dot_j_out_vec_p2 + 6.0*j_out_p2*j_in_vec_dot_e_out_vec_p2 - 3.0*h2*j_in_vec_dot_j_out_vec_p2; - g3 = h3*j_out_p4 - 693.0*h2*e_in_vec_dot_j_out_vec_p4 + 42.0*e_in_vec_dot_j_out_vec_p2*(h4*j_out_p2 + 9.0*h2*j_in_vec_dot_j_out_vec_p2) \ - + 14.0*h5*j_in_vec_dot_j_out_vec_p2*j_out_p2 - 21.0*h2*j_in_vec_dot_j_out_vec_p4 \ - - 28.0*j_in_vec_dot_e_out_vec_p2*j_out_p2*( (1.0 + 23.0*e_in_p2)*j_out_p2 - 9.0*j_in_vec_dot_j_out_vec_p2 ); - - g = -3024.0*e_in_vec_dot_e_out_vec_p2*e_in_vec_dot_j_out_vec*j_in_vec_dot_e_out_vec*j_in_vec_dot_j_out_vec*j_out_p2 \ - + 28.0*j_out_p2*e_in_vec_dot_e_out_vec_p3*g1 + 28.0*e_in_vec_dot_j_out_vec*j_in_vec_dot_e_out_vec*j_in_vec_dot_j_out_vec*g2 \ - + e_in_vec_dot_e_out_vec*g3; - -// f12 = 3.0*f4*j_out_p4 + 420.0*e_in_vec_dot_e_out_vec_p2*j_out_p2*f5 \ - - 5880.0*j_out_p2*e_in_vec_dot_e_out_vec*j_in_vec_dot_e_out_vec*e_in_vec_dot_j_out_vec*j_in_vec_dot_j_out_vec \ - + 5.0*( 28.0*j_out_p2*f6*e_in_vec_dot_j_out_vec_p2 \ - - 6.0*j_out_p2*f7*j_in_vec_dot_j_out_vec_p2 ); - } - - double binary_pair_hamiltonian = A_quad*j_out_p5_inv*f1 - A_oct*j_out_p7_inv*( e_in_vec_dot_e_out_vec*f2 + f3 ) \ - + A_hd*j_out_p11_inv*f12 + A_tc*j_out_p13_inv*g; - - - if (compute_hamiltonian_only == true) - { - return binary_pair_hamiltonian; - } - - - /**************************************** - * compute gradients of the Hamiltonian * - ***************************************/ - double grad_e_in_vec_phi[3], grad_j_in_vec_phi[3]; - double grad_e_out_vec_phi[3], grad_j_out_vec_phi[3]; - - double grad_j_in_vec_f1[3], grad_j_in_vec_f2[3], grad_j_in_vec_f3[3]; - double grad_j_out_vec_f1[3], grad_j_out_vec_f2[3], grad_j_out_vec_f3[3]; - double grad_e_in_vec_f1[3], grad_e_in_vec_f2[3], grad_e_in_vec_f3[3]; - double grad_e_out_vec_f3[3]; - - /* triacontadipole */ - double grad_j_in_vec_g1[3], grad_j_in_vec_g2[3], grad_j_in_vec_g3[3]; - double grad_j_out_vec_g1[3], grad_j_out_vec_g2[3], grad_j_out_vec_g3[3]; - double grad_e_in_vec_g1[3], grad_e_in_vec_g2[3], grad_e_in_vec_g3[3]; - double grad_e_out_vec_g2[3], grad_e_out_vec_g3[3]; - - -#ifdef IGNORE - if (include_octupole_order_binary_pair_terms == true) - { - printf("include_octupole_order_binary_pair_terms\n"); - } - if (include_hexadecupole_order_binary_pair_terms == true) - { - printf("include_hexadecupole_order_binary_pair_terms\n"); - } - if (include_dotriacontupole_order_binary_pair_terms == true) - { - printf("include_dotriacontupole_order_binary_pair_terms\n"); - } -#endif - - for (int i=0; i<3; i++) - { - /* separate terms occurring in the gradients */ - if (include_quadrupole_order_terms == true) - { - grad_j_in_vec_f1[i] = -6.0*j_in_vec_dot_j_out_vec*j_out_vec[i]; - grad_j_out_vec_f1[i] = -6.0*j_in_vec_dot_j_out_vec*j_in_vec[i] + 2.0*(1.0-6.0*e_in_p2)*j_out_vec[i] \ - + 30.0*e_in_vec_dot_j_out_vec*e_in_vec[i]; - grad_e_in_vec_f1[i] = -12.0*j_out_p2*e_in_vec[i] + 30.0*e_in_vec_dot_j_out_vec*j_out_vec[i]; - } - if (include_octupole_order_binary_pair_terms == true) - { - grad_j_in_vec_f2[i] = -10.0*j_in_vec_dot_j_out_vec*j_out_vec[i]; - grad_j_in_vec_f3[i] = -10.0*e_in_vec_dot_j_out_vec*( j_in_vec_dot_j_out_vec*e_out_vec[i] + j_in_vec_dot_e_out_vec*j_out_vec[i] ); - grad_j_out_vec_f2[i] = -10.0*j_in_vec_dot_j_out_vec*j_in_vec[i] + 2.0*(1.0-8.0*e_in_p2)*j_out_vec[i] \ - + 70.0*e_in_vec_dot_j_out_vec*e_in_vec[i]; - grad_j_out_vec_f3[i] = -10.0*j_in_vec_dot_e_out_vec*( j_in_vec_dot_j_out_vec*e_in_vec[i] + e_in_vec_dot_j_out_vec*j_in_vec[i] ); - grad_e_in_vec_f2[i] = -16.0*j_out_p2*e_in_vec[i] + 70.0*e_in_vec_dot_j_out_vec*j_out_vec[i]; - grad_e_in_vec_f3[i] = -10.0*j_in_vec_dot_e_out_vec*j_in_vec_dot_j_out_vec*j_out_vec[i]; - grad_e_out_vec_f3[i] = -10.0*e_in_vec_dot_j_out_vec*j_in_vec_dot_j_out_vec*j_in_vec[i]; - } - if (include_dotriacontupole_order_binary_pair_terms == true) - { - grad_j_in_vec_g1[i] = 36.0*j_in_vec_dot_j_out_vec*j_out_vec[i]; - grad_j_in_vec_g2[i] = 12.0*j_out_p2*j_in_vec_dot_e_out_vec*e_out_vec[i] - 6.0*h2*j_in_vec_dot_j_out_vec*j_out_vec[i]; - grad_j_in_vec_g3[i] = 756.0*e_in_vec_dot_j_out_vec_p2*h2*j_in_vec_dot_j_out_vec*j_out_vec[i] + 28.0*h5*j_in_vec_dot_j_out_vec*j_out_p2*j_out_vec[i] \ - - 84.0*h2*j_in_vec_dot_j_out_vec_p3*j_out_vec[i] - 56.0*j_in_vec_dot_e_out_vec*j_out_p2*((1.0 + 23.0*e_in_p2)*j_out_p2 - 9.0*j_in_vec_dot_j_out_vec_p2)*e_out_vec[i] \ - + 504.0*j_in_vec_dot_e_out_vec_p2*j_out_p2*j_in_vec_dot_j_out_vec*j_out_vec[i]; - - grad_j_out_vec_g1[i] = 2.0*(-26.0 + 15.0*e_in_p2)*j_out_vec[i] + 36.0*j_in_vec_dot_j_out_vec*j_in_vec[i] + 198.0*e_in_vec_dot_j_out_vec*e_in_vec[i]; - grad_j_out_vec_g2[i] = 2.0*h1*j_out_vec[i] + 18.0*h2*e_in_vec_dot_j_out_vec*e_in_vec[i] + 12.0*j_in_vec_dot_e_out_vec_p2*j_out_vec[i] \ - - 6.0*h2*j_in_vec_dot_j_out_vec*j_in_vec[i]; - grad_j_out_vec_g3[i] = 4.0*h3*j_out_p2*j_out_vec[i] - 2772.0*h2*e_in_vec_dot_j_out_vec_p3*e_in_vec[i] \ - + 84.0*e_in_vec_dot_j_out_vec*( h4*j_out_p2 + 9.0*h2*j_in_vec_dot_j_out_vec_p2 )*e_in_vec[i] \ - + 42.0*e_in_vec_dot_j_out_vec_p2*( 2.0*h4*j_out_vec[i] + 18.0*h2*j_in_vec_dot_j_out_vec*j_in_vec[i] ) \ - + 28.0*h5*( j_out_p2*j_in_vec_dot_j_out_vec*j_in_vec[i] + j_in_vec_dot_j_out_vec_p2*j_out_vec[i] ) \ - - 84.0*h2*j_in_vec_dot_j_out_vec_p3*j_in_vec[i] \ - - 28.0*j_in_vec_dot_e_out_vec_p2*( 2.0*j_out_vec[i]*( (1.0 + 23.0*e_in_p2)*j_out_p2 - 9.0*j_in_vec_dot_j_out_vec_p2 ) \ - + j_out_p2*( 2.0*(1.0 + 23.0*e_in_p2)*j_out_vec[i] - 18.0*j_in_vec_dot_j_out_vec*j_in_vec[i]) ); - - grad_e_in_vec_g1[i] = 30.0*j_out_p2*e_in_vec[i] + 198.0*e_in_vec_dot_j_out_vec*j_out_vec[i]; - grad_e_in_vec_g2[i] = -8.0*(8.0 + e_out_p2)*j_out_p2*e_in_vec[i] + 18.0*e_in_vec_dot_j_out_vec*h2*j_out_vec[i]; - grad_e_in_vec_g3[i] = j_out_p4*( -16.0*e_in_p2*(80.0 + 179.0*e_out_p2) + 2.0*(64.0 + 748.0*e_out_p2) )*e_in_vec[i] \ - - 2772.0*h2*e_in_vec_dot_j_out_vec_p3*j_out_vec[i] + 84.0*e_in_vec_dot_j_out_vec*( h4*j_out_p2 + 9.0*h2*j_in_vec_dot_j_out_vec_p2 )*j_out_vec[i] \ - + 504.0*e_in_vec_dot_j_out_vec_p2*j_out_p2*(16.0 + 5.0*e_out_p2)*e_in_vec[i] - 56.0*j_in_vec_dot_j_out_vec_p2*j_out_p2*(16.0 + 29.0*e_out_p2)*e_in_vec[i] \ - - 1288.0*j_in_vec_dot_e_out_vec_p2*j_out_p4*e_in_vec[i]; - - grad_e_out_vec_g2[i] = 2.0*(1.0 - 4.0*e_in_p2)*j_out_p2*e_out_vec[i] + 54.0*e_in_vec_dot_j_out_vec_p2*e_out_vec[i] \ - + 12.0*j_out_p2*j_in_vec_dot_e_out_vec*j_in_vec[i] - 18.0*j_in_vec_dot_j_out_vec_p2*e_out_vec[i]; - grad_e_out_vec_g3[i] = j_out_p4*( 2.0 + 1496.0*e_in_p2 -1432.0*e_in_p4 )*e_out_vec[i] - 4158.0*e_in_vec_dot_j_out_vec_p4*e_out_vec[i] \ - + 42.0*e_in_vec_dot_j_out_vec_p2*( (-38.0 + 60.0*e_in_p2)*j_out_p2 + 54.0*j_in_vec_dot_j_out_vec_p2 )*e_out_vec[i] \ - + 14.0*j_in_vec_dot_j_out_vec_p2*j_out_p2*(2.0 - 116.0*e_in_p2)*e_out_vec[i] - 126.0*j_in_vec_dot_j_out_vec_p4*e_out_vec[i] \ - - 56.0*j_in_vec_dot_e_out_vec*j_out_p2*( (1.0 + 23.0*e_in_p2)*j_out_p2 - 9.0*j_in_vec_dot_j_out_vec_p2 )*j_in_vec[i]; - } - - /* complete gradients */ - grad_j_in_vec_phi[i] = 0.0; - grad_j_out_vec_phi[i] = 0.0; - grad_e_in_vec_phi[i] = 0.0; - grad_e_out_vec_phi[i] = 0.0; - - if (include_quadrupole_order_terms == true) - { - grad_j_in_vec_phi[i] += A_quad*j_out_p5_inv*grad_j_in_vec_f1[i]; - grad_j_out_vec_phi[i] += -5.0*A_quad*j_out_p7_inv*j_out_vec[i]*f1 + A_quad*j_out_p5_inv*grad_j_out_vec_f1[i]; - grad_e_in_vec_phi[i] += A_quad*j_out_p5_inv*grad_e_in_vec_f1[i]; - } - if (include_octupole_order_binary_pair_terms == true) - { - grad_j_in_vec_phi[i] += -A_oct*j_out_p7_inv*( e_in_vec_dot_e_out_vec*grad_j_in_vec_f2[i] + grad_j_in_vec_f3[i] ); - grad_j_out_vec_phi[i] += 7.0*A_oct*j_out_p9_inv*j_out_vec[i]*( e_in_vec_dot_e_out_vec*f2 + f3 ) \ - - A_oct*j_out_p7_inv*( e_in_vec_dot_e_out_vec*grad_j_out_vec_f2[i] + grad_j_out_vec_f3[i] ); - grad_e_in_vec_phi[i] += -A_oct*j_out_p7_inv*( e_out_vec[i]*f2 + e_in_vec_dot_e_out_vec*grad_e_in_vec_f2[i] \ - + grad_e_in_vec_f3[i] ); - grad_e_out_vec_phi[i] += -A_oct*j_out_p7_inv*( e_in_vec[i]*f2 + grad_e_out_vec_f3[i] ); - } - if (include_hexadecupole_order_binary_pair_terms == true) - { - grad_j_in_vec_phi[i] += A_hd*j_out_p11_inv*( \ - - 5880.0*j_out_p2*e_in_vec_dot_e_out_vec*e_in_vec_dot_j_out_vec*(j_in_vec_dot_j_out_vec*e_out_vec[i] + j_in_vec_dot_e_out_vec*j_out_vec[i]) \ - + 5.0*( -12.0*j_out_p2*f7*j_in_vec_dot_j_out_vec*j_out_vec[i] - 12.0*j_out_p2*(2.0*f8*j_in_vec_dot_e_out_vec*e_out_vec[i] \ - - 14.0*j_in_vec_dot_e_out_vec_p2*j_in_vec_dot_j_out_vec*j_out_vec[i]) \ - + 84.0*f11*f10*j_in_vec_dot_j_out_vec*j_out_vec[i] \ - - 84.0*f11*j_in_vec_dot_j_out_vec_p2*j_in_vec_dot_j_out_vec*j_out_vec[i] ) \ - ); - grad_j_out_vec_phi[i] += -11.0*A_hd*j_out_p11_inv*j_out_p2_inv*f12*j_out_vec[i] \ - + A_hd*j_out_p11_inv*(12.0*f4*j_out_p2*j_out_vec[i] \ - + 420.0*e_in_vec_dot_e_out_vec_p2*(2.0*f5*j_out_vec[i] + j_out_p2*(-4.0*j_out_vec[i] - 2.0*e_in_p2*j_out_vec[i] + 42.0*e_in_vec_dot_j_out_vec*e_in_vec[i])) \ - - 5880.0*e_in_vec_dot_e_out_vec*j_in_vec_dot_e_out_vec*(2.0*e_in_vec_dot_j_out_vec*j_in_vec_dot_j_out_vec*j_out_vec[i] \ - + j_out_p2*j_in_vec_dot_j_out_vec*e_in_vec[i] + j_out_p2*e_in_vec_dot_j_out_vec*j_in_vec[i]) \ - + 5.0*( \ - + 56.0*f6*(e_in_vec_dot_j_out_vec_p2*j_out_vec[i] + j_out_p2*e_in_vec_dot_j_out_vec*e_in_vec[i]) \ - - 12.0*f7*(j_in_vec_dot_j_out_vec_p2*j_out_vec[i] + j_out_p2*j_in_vec_dot_j_out_vec*j_in_vec[i]) \ - - 12.0*j_in_vec_dot_e_out_vec_p2*(2.0*f8*j_out_vec[i] + j_out_p2*(2.0*j_out_vec[i] + 26.0*e_in_p2*j_out_vec[i] - 14.0*j_in_vec_dot_j_out_vec*j_in_vec[i]) ) \ - + 196.0*f9*(e_in_vec_dot_j_out_vec_p2*j_out_vec[i] + j_out_p2*e_in_vec_dot_j_out_vec*e_in_vec[i]) \ - - 1764.0*f11*e_in_vec_dot_j_out_vec_p2*e_in_vec_dot_j_out_vec*e_in_vec[i] \ - + 42.0*f11*( j_in_vec_dot_j_out_vec_p2*(2.0*j_out_vec[i] - 2.0*e_in_p2*j_out_vec[i] + 14.0*e_in_vec_dot_j_out_vec*e_in_vec[i]) \ - + 2.0*f10*j_in_vec_dot_j_out_vec*j_in_vec[i] ) - 84.0*f11*j_in_vec_dot_j_out_vec_p2*j_in_vec_dot_j_out_vec*j_in_vec[i] ) \ - ); - grad_e_in_vec_phi[i] += A_hd*j_out_p11_inv*( \ - + 240.0*j_out_p4*(1.0 + 8.0*e_out_p2 - e_in_p2*(8.0 + 15.0*e_out_p2))*e_in_vec[i] + 840.0*e_in_vec_dot_e_out_vec*j_out_p2*f5*e_out_vec[i] \ - + 420.0*e_in_vec_dot_e_out_vec_p2*j_out_p2*(-2.0*j_out_p2*e_in_vec[i] + 42.0*e_in_vec_dot_j_out_vec*j_out_vec[i]) \ - - 5880.0*j_out_p2*j_in_vec_dot_e_out_vec*j_in_vec_dot_j_out_vec*( e_in_vec_dot_j_out_vec*e_out_vec[i] + e_in_vec_dot_e_out_vec*j_out_vec[i] ) \ - + 5.0*( \ - + 28.0*j_out_p2*(4.0 + 3.0*e_out_p2)*( -20.0*e_in_vec_dot_j_out_vec_p2*e_in_vec[i] + 2.0*(1.0 - 10.0*e_in_p2)*e_in_vec_dot_j_out_vec*j_out_vec[i] ) \ - - 12.0*j_out_p2*(6.0 + 29.0*e_out_p2)*j_in_vec_dot_j_out_vec_p2*e_in_vec[i] - 312.0*j_out_p4*j_in_vec_dot_e_out_vec_p2*e_in_vec[i] \ - + 98.0*j_out_p2*(8.0*e_in_vec_dot_j_out_vec_p2*(5.0 + 3.0*e_out_p2)*e_in_vec[i] + 2.0*e_in_vec_dot_j_out_vec*f9*j_out_vec[i]) \ - - 1764.0*f11*e_in_vec_dot_j_out_vec_p2*e_in_vec_dot_j_out_vec*j_out_vec[i] \ - + 42.0*f11*j_in_vec_dot_j_out_vec_p2*(-2.0*j_out_p2*e_in_vec[i] + 14.0*e_in_vec_dot_j_out_vec*j_out_vec[i]) ) \ - ); - grad_e_out_vec_phi[i] += A_hd*j_out_p11_inv*( \ - + 6.0*j_out_p4*(1.0 + 320.0*e_in_p2 - 300.0*e_in_p4)*e_out_vec[i] + 840.0*e_in_vec_dot_e_out_vec*j_out_p2*f5*e_in_vec[i] \ - - 5880.0*j_out_p2*e_in_vec_dot_j_out_vec*j_in_vec_dot_j_out_vec*(j_in_vec_dot_e_out_vec*e_in_vec[i] + e_in_vec_dot_e_out_vec*j_in_vec[i]) \ - + 5.0*( \ - + 168.0*j_out_p2*(1.0 - 10.0*e_in_p2)*e_in_vec_dot_j_out_vec_p2*e_out_vec[i] - 6.0*j_out_p2*j_in_vec_dot_j_out_vec_p2*(12.0 + 58.0*e_in_p2)*e_out_vec[i] \ - - 24.0*j_out_p2*f8*j_in_vec_dot_e_out_vec*j_in_vec[i] + 98.0*j_out_p2*e_in_vec_dot_j_out_vec_p2*(-6.0 + 24.0*e_in_p2)*e_out_vec[i] \ - - 882.0*e_in_vec_dot_j_out_vec_p4*e_out_vec[i] + 84.0*f10*j_in_vec_dot_j_out_vec_p2*e_out_vec[i] - 42.0*j_in_vec_dot_j_out_vec_p4*e_out_vec[i]) \ - ); - } - if (include_dotriacontupole_order_binary_pair_terms == true) - { - grad_j_in_vec_phi[i] += A_tc*j_out_p13_inv*( \ - - 3024.0*e_in_vec_dot_e_out_vec_p2*e_in_vec_dot_j_out_vec*j_out_p2*( j_in_vec_dot_j_out_vec*e_out_vec[i] + j_in_vec_dot_e_out_vec*j_out_vec[i] ) \ - + 28.0*j_out_p2*e_in_vec_dot_e_out_vec_p3*grad_j_in_vec_g1[i] + 28.0*e_in_vec_dot_j_out_vec*( j_in_vec_dot_j_out_vec*g2*e_out_vec[i] \ - + j_in_vec_dot_e_out_vec*g2*j_out_vec[i] + j_in_vec_dot_e_out_vec*j_in_vec_dot_j_out_vec*grad_j_in_vec_g2[i] ) \ - + e_in_vec_dot_e_out_vec*grad_j_in_vec_g3[i] ); - grad_j_out_vec_phi[i] += -13.0*A_tc*j_out_p13_inv*j_out_p2_inv*g*j_out_vec[i] + A_tc*j_out_p13_inv*( \ - - 3024.0*e_in_vec_dot_e_out_vec_p2*j_in_vec_dot_e_out_vec*( j_in_vec_dot_j_out_vec*j_out_p2*e_in_vec[i] + e_in_vec_dot_j_out_vec*j_out_p2*j_in_vec[i] \ - + 2.0*e_in_vec_dot_j_out_vec*j_in_vec_dot_j_out_vec*j_out_vec[i] ) + 28.0*e_in_vec_dot_e_out_vec_p3*( 2.0*g1*j_out_vec[i] + j_out_p2*grad_j_out_vec_g1[i] ) \ - + 28.0*j_in_vec_dot_e_out_vec*( j_in_vec_dot_j_out_vec*g2*e_in_vec[i] + e_in_vec_dot_j_out_vec*g2*j_in_vec[i] \ - + e_in_vec_dot_j_out_vec*j_in_vec_dot_j_out_vec*grad_j_out_vec_g2[i] ) + e_in_vec_dot_e_out_vec*grad_j_out_vec_g3[i] ); - grad_e_in_vec_phi[i] += A_tc*j_out_p13_inv*( \ - - 3024.0*j_in_vec_dot_e_out_vec*j_in_vec_dot_j_out_vec*j_out_p2*( 2.0*e_in_vec_dot_e_out_vec*e_in_vec_dot_j_out_vec*e_out_vec[i] \ - + e_in_vec_dot_e_out_vec_p2*j_out_vec[i] ) + 84.0*j_out_p2*e_in_vec_dot_e_out_vec_p2*g1*e_out_vec[i] \ - + 28.0*j_out_p2*e_in_vec_dot_e_out_vec_p3*grad_e_in_vec_g1[i] + 28.0*j_in_vec_dot_e_out_vec*j_in_vec_dot_j_out_vec*( g2*j_out_vec[i] \ - + e_in_vec_dot_j_out_vec*grad_e_in_vec_g2[i] ) + g3*e_out_vec[i] + e_in_vec_dot_e_out_vec*grad_e_in_vec_g3[i] ); - grad_e_out_vec_phi[i] += A_tc*j_out_p13_inv*( \ - - 3024.0*e_in_vec_dot_j_out_vec*j_in_vec_dot_j_out_vec*j_out_p2*( 2.0*j_in_vec_dot_e_out_vec*e_in_vec_dot_e_out_vec*e_in_vec[i] \ - + e_in_vec_dot_e_out_vec_p2*j_in_vec[i] ) + 84.0*j_out_p2*e_in_vec_dot_e_out_vec_p2*g1*e_in_vec[i] \ - + 28.0*e_in_vec_dot_j_out_vec*j_in_vec_dot_j_out_vec*( g2*j_in_vec[i] + j_in_vec_dot_e_out_vec*grad_e_out_vec_g2[i] ) \ - + g3*e_in_vec[i] + e_in_vec_dot_e_out_vec*grad_e_out_vec_g3[i] ); - } - } - - double j_in_vec_cross_grad_j_in_vec_phi[3], j_in_vec_cross_grad_e_in_vec_phi[3]; - double j_out_vec_cross_grad_j_out_vec_phi[3], j_out_vec_cross_grad_e_out_vec_phi[3]; - - double e_in_vec_cross_grad_e_in_vec_phi[3], e_in_vec_cross_grad_j_in_vec_phi[3]; - double e_out_vec_cross_grad_e_out_vec_phi[3], e_out_vec_cross_grad_j_out_vec_phi[3]; - - - cross3(j_in_vec, grad_j_in_vec_phi, j_in_vec_cross_grad_j_in_vec_phi); - cross3(j_in_vec, grad_e_in_vec_phi, j_in_vec_cross_grad_e_in_vec_phi); - cross3(e_in_vec, grad_e_in_vec_phi, e_in_vec_cross_grad_e_in_vec_phi); - cross3(e_in_vec, grad_j_in_vec_phi, e_in_vec_cross_grad_j_in_vec_phi); - - cross3(j_out_vec, grad_j_out_vec_phi, j_out_vec_cross_grad_j_out_vec_phi); - cross3(j_out_vec, grad_e_out_vec_phi, j_out_vec_cross_grad_e_out_vec_phi); - cross3(e_out_vec, grad_e_out_vec_phi, e_out_vec_cross_grad_e_out_vec_phi); - cross3(e_out_vec, grad_j_out_vec_phi, e_out_vec_cross_grad_j_out_vec_phi); - - - for (int i=0; i<3; i++) - { - inner_binary->de_vec_dt[i] += (-1.0/(Lambda_in))*( e_in_vec_cross_grad_j_in_vec_phi[i] \ - + j_in_vec_cross_grad_e_in_vec_phi[i] ); - inner_binary->dh_vec_dt[i] += -1.0*( j_in_vec_cross_grad_j_in_vec_phi[i] \ - + e_in_vec_cross_grad_e_in_vec_phi[i] ); - - outer_binary->de_vec_dt[i] += (-1.0/(Lambda_out))*( e_out_vec_cross_grad_j_out_vec_phi[i] \ - + j_out_vec_cross_grad_e_out_vec_phi[i] ); - outer_binary->dh_vec_dt[i] += -1.0*( j_out_vec_cross_grad_j_out_vec_phi[i] \ - + e_out_vec_cross_grad_e_out_vec_phi[i] ); - - //printf("testtttt %g %g \n",inner_binary->de_vec_dt[i],inner_binary->dh_vec_dt[i]); - } - - return binary_pair_hamiltonian; - - if (1==0) - { - printf("e_in %g %g %g\n",e_in_vec[0],e_in_vec[1],e_in_vec[2]); - printf("e_out %g %g %g\n",e_out_vec[0],e_out_vec[1],e_out_vec[2]); - printf("h_in %g %g %g\n",h_in_vec[0],h_in_vec[1],h_in_vec[2]); - printf("h_out %g %g %g\n",h_out_vec[0],h_out_vec[1],h_out_vec[2]); - - printf("grad1 %g %g %g\n",grad_e_in_vec_f1[0],grad_e_in_vec_f1[1],grad_e_in_vec_f1[2]); - printf("grad2 %g %g %g\n",grad_e_in_vec_f2[0],grad_e_in_vec_f2[1],grad_e_in_vec_f2[2]); - printf("grad3 %g %g %g\n",grad_e_in_vec_f3[0],grad_e_in_vec_f3[1],grad_e_in_vec_f3[2]); - - printf("de_in_dt %g %g %g\n",inner_binary->de_vec_dt[0],inner_binary->de_vec_dt[1],inner_binary->de_vec_dt[2]); - printf("de_out_dt %g %g %g\n",outer_binary->de_vec_dt[0],outer_binary->de_vec_dt[1],outer_binary->de_vec_dt[2]); - printf("dh_in_dt %g %g %g\n",inner_binary->dh_vec_dt[0],inner_binary->dh_vec_dt[1],inner_binary->dh_vec_dt[2]); - printf("dh_out_dt %g %g %g\n",outer_binary->dh_vec_dt[0],outer_binary->dh_vec_dt[1],outer_binary->dh_vec_dt[2]); - } -} - - - -double compute_EOM_binary_triplets(ParticlesMap *particlesMap, int binary_A_index, int binary_B_index, int binary_C_index, int connecting_child_in_binary_B_to_binary_A, int connecting_child_in_binary_C_to_binary_B, bool compute_hamiltonian_only) -{ - /* last checked 23-06-15 */ - - if (include_octupole_order_binary_triplet_terms == false) - { - return 0.0; - } - - /********************* - * preamble * - ********************/ - - Particle *binary_A = (*particlesMap)[binary_A_index]; - Particle *binary_B = (*particlesMap)[binary_B_index]; - Particle *binary_C = (*particlesMap)[binary_C_index]; - - Particle *binary_A_child1 = (*particlesMap)[binary_A->child1]; - Particle *binary_A_child2 = (*particlesMap)[binary_A->child2]; - - Particle *binary_B_child1 = (*particlesMap)[binary_B->child1]; - Particle *binary_B_child2 = (*particlesMap)[binary_B->child2]; - - Particle *binary_C_child1 = (*particlesMap)[binary_C->child1]; - Particle *binary_C_child2 = (*particlesMap)[binary_C->child2]; - - /* set alpha = +1 */ - double B_ijB = 0.0; - - if (connecting_child_in_binary_B_to_binary_A==1) - { - B_ijB = binary_B_child2->mass/binary_B->mass; - } - else if (connecting_child_in_binary_B_to_binary_A==2) - { - B_ijB = -binary_B_child1->mass/binary_B->mass; - } - - double M_C_CS_B = 0.0; - - if (connecting_child_in_binary_C_to_binary_B==1) - { - M_C_CS_B = binary_C_child2->mass; - } - else if (connecting_child_in_binary_C_to_binary_B==2) - { - M_C_CS_B = binary_C_child1->mass; - } - - double e_A = binary_A->e; - double e_B = binary_B->e; - double e_C = binary_C->e; - double e_A_p2 = binary_A->e_p2; - double e_B_p2 = binary_B->e_p2; - double e_C_p2 = binary_C->e_p2; - - double *e_A_vec = binary_A->e_vec; - double *e_B_vec = binary_B->e_vec; - double *e_C_vec = binary_C->e_vec; - - double *h_A_vec = binary_A->h_vec; - double *h_B_vec = binary_B->h_vec; - double *h_C_vec = binary_C->h_vec; - - double *e_A_vec_unit = binary_A->e_vec_unit; - double *e_B_vec_unit = binary_B->e_vec_unit; - double *e_C_vec_unit = binary_C->e_vec_unit; - - double *h_A_vec_unit = binary_A->h_vec_unit; - double *h_B_vec_unit = binary_B->h_vec_unit; - double *h_C_vec_unit = binary_C->h_vec_unit; - - double *j_A_vec_unit = h_A_vec_unit; - double *j_B_vec_unit = h_B_vec_unit; - double *j_C_vec_unit = h_C_vec_unit; - - double h_A = binary_A->h; - double h_B = binary_B->h; - double h_C = binary_C->h; - - double j_A = binary_A->j; - double j_A_p2 = binary_A->j_p2; - double j_B = binary_B->j; -// double j_B_p2 = binary_B->j_p2; - double j_C = binary_C->j; - double j_C_p2 = binary_C->j_p2; - double j_C_p4 = binary_C->j_p4; - double j_C_p7 = j_C*j_C_p2*j_C_p4; - double j_C_p9 = j_C_p7*j_C_p2; - - double j_C_p7_inv = 1.0/j_C_p7; - double j_C_p9_inv = 1.0/j_C_p9; - - double j_A_vec[3],j_B_vec[3],j_C_vec[3]; - for (int i=0; i<3; i++) - { - j_A_vec[i] = j_A*h_A_vec_unit[i]; - j_B_vec[i] = j_B*h_B_vec_unit[i]; - j_C_vec[i] = j_C*h_C_vec_unit[i]; - } - - double a_A = binary_A->a; - double a_B = binary_B->a; - double a_C = binary_C->a; - - double M_A1 = binary_A_child1->mass; - double M_A2 = binary_A_child2->mass; - - double A_cross = -(c_9div32*M_A1*M_A2*B_ijB*M_C_CS_B/(M_A1 + M_A2))*(a_A*a_A*a_B/(a_C*a_C*a_C*a_C)); - double Lambda_A = h_A/j_A; - double Lambda_B = h_B/j_B; - double Lambda_C = h_C/j_C; - - double e_A_vec_dot_e_B_vec = dot3(e_A_vec,e_B_vec); - double e_B_vec_dot_e_C_vec = dot3(e_B_vec,e_C_vec); - double e_A_vec_dot_e_C_vec = dot3(e_A_vec,e_C_vec); - - double e_A_vec_dot_j_C_vec = dot3(e_A_vec,j_C_vec); - double e_B_vec_dot_j_C_vec = dot3(e_B_vec,j_C_vec); - double e_B_vec_dot_j_A_vec = dot3(e_B_vec,j_A_vec); - double e_C_vec_dot_j_A_vec = dot3(e_C_vec,j_A_vec); - double j_A_vec_dot_j_C_vec = dot3(j_A_vec,j_C_vec); - - double e_A_vec_dot_j_C_vec_p2 = e_A_vec_dot_j_C_vec*e_A_vec_dot_j_C_vec; - double j_A_vec_dot_j_C_vec_p2 = j_A_vec_dot_j_C_vec*j_A_vec_dot_j_C_vec; - - /*************************** - * compute the Hamiltonian * - **************************/ - - double f1 = j_C_p2*(1.0 - 6.0*e_A_p2) + 25.0*e_A_vec_dot_j_C_vec_p2 - 5.0*j_A_vec_dot_j_C_vec_p2; - double f0 = -10.0*e_A_vec_dot_e_B_vec*e_A_vec_dot_e_C_vec*j_C_p2 + 50.0*e_A_vec_dot_e_C_vec*e_A_vec_dot_j_C_vec*e_B_vec_dot_j_C_vec \ - + 2.0*e_C_vec_dot_j_A_vec*e_B_vec_dot_j_A_vec*j_C_p2 - 10.0*e_B_vec_dot_j_C_vec*e_C_vec_dot_j_A_vec*j_A_vec_dot_j_C_vec \ - + e_B_vec_dot_e_C_vec*f1; - - double binary_triplet_hamiltonian = A_cross*j_C_p7_inv*f0; -// cross_term_hamiltonian *= -1.0; - - if (compute_hamiltonian_only == true) - { - return binary_triplet_hamiltonian; - } - - /**************************************** - * compute gradients of the Hamiltonian * - ***************************************/ - double grad_e_A_vec_H[3], grad_j_A_vec_H[3]; - double grad_e_B_vec_H[3], grad_j_B_vec_H[3]; - double grad_e_C_vec_H[3], grad_j_C_vec_H[3]; - - for (int i=0; i<3; i++) - { - - /* gradient w.r.t. e_A */ - grad_e_A_vec_H[i] = A_cross*j_C_p7_inv*( \ - - 10.0*j_C_p2*(e_A_vec_dot_e_C_vec*e_B_vec[i] + e_A_vec_dot_e_B_vec*e_C_vec[i]) \ - + 50.0*e_B_vec_dot_j_C_vec*(e_A_vec_dot_j_C_vec*e_C_vec[i] + e_A_vec_dot_e_C_vec*j_C_vec[i]) \ - + e_B_vec_dot_e_C_vec*(50.0*e_A_vec_dot_j_C_vec*j_C_vec[i] - 12.0*j_C_p2*e_A_vec[i]) ); - - /* gradient w.r.t. j_A */ - grad_j_A_vec_H[i] = A_cross*j_C_p7_inv*( \ - + 2.0*e_B_vec_dot_j_A_vec*j_C_p2*e_C_vec[i] + 2.0*e_C_vec_dot_j_A_vec*j_C_p2*e_B_vec[i] \ - - 10.0*e_B_vec_dot_j_C_vec*(j_A_vec_dot_j_C_vec*e_C_vec[i] + e_C_vec_dot_j_A_vec*j_C_vec[i]) \ - - 10.0*e_B_vec_dot_e_C_vec*j_A_vec_dot_j_C_vec*j_C_vec[i] ); - - /* gradient w.r.t. e_B */ - grad_e_B_vec_H[i] = A_cross*j_C_p7_inv*( \ - - 10.0*e_A_vec_dot_e_C_vec*j_C_p2*e_A_vec[i] + 50.0*e_A_vec_dot_e_C_vec*e_A_vec_dot_j_C_vec*j_C_vec[i] \ - + 2.0*e_C_vec_dot_j_A_vec*j_C_p2*j_A_vec[i] - 10.0*e_C_vec_dot_j_A_vec*j_A_vec_dot_j_C_vec*j_C_vec[i] \ - + f1*e_C_vec[i] ); - - /* gradient w.r.t. j_B */ - grad_j_B_vec_H[i] = 0.0; - - /* gradient w.r.t. e_C */ - grad_e_C_vec_H[i] = A_cross*j_C_p7_inv*( \ - - 10.0*e_A_vec_dot_e_B_vec*j_C_p2*e_A_vec[i] + 50.0*e_A_vec_dot_j_C_vec*e_B_vec_dot_j_C_vec*e_A_vec[i] \ - + 2.0*e_B_vec_dot_j_A_vec*j_C_p2*j_A_vec[i] - 10.0*e_B_vec_dot_j_C_vec*j_A_vec_dot_j_C_vec*j_A_vec[i] \ - + f1*e_B_vec[i] ); - - /* gradient w.r.t. j_C */ - grad_j_C_vec_H[i] = -7.0*A_cross*j_C_p9_inv*f0*j_C_vec[i] + A_cross*j_C_p7_inv*( \ - - 20.0*e_A_vec_dot_e_B_vec*e_A_vec_dot_e_C_vec*j_C_vec[i] \ - + 50.0*e_A_vec_dot_e_C_vec*(e_B_vec_dot_j_C_vec*e_A_vec[i] + e_A_vec_dot_j_C_vec*e_B_vec[i]) \ - + 4.0*e_C_vec_dot_j_A_vec*e_B_vec_dot_j_A_vec*j_C_vec[i] \ - - 10.0*e_C_vec_dot_j_A_vec*(j_A_vec_dot_j_C_vec*e_B_vec[i] + e_B_vec_dot_j_C_vec*j_A_vec[i]) \ - + e_B_vec_dot_e_C_vec*(2.0*(1.0 - 6.0*e_A_p2)*j_C_vec[i] + 50.0*e_A_vec_dot_j_C_vec*e_A_vec[i] \ - - 10.0*j_A_vec_dot_j_C_vec*j_A_vec[i]) ); - - } - - double j_A_vec_cross_grad_j_A_vec_H[3], j_A_vec_cross_grad_e_A_vec_H[3]; - double j_B_vec_cross_grad_j_B_vec_H[3], j_B_vec_cross_grad_e_B_vec_H[3]; - double j_C_vec_cross_grad_j_C_vec_H[3], j_C_vec_cross_grad_e_C_vec_H[3]; - - double e_A_vec_cross_grad_e_A_vec_H[3], e_A_vec_cross_grad_j_A_vec_H[3]; - double e_B_vec_cross_grad_e_B_vec_H[3], e_B_vec_cross_grad_j_B_vec_H[3]; - double e_C_vec_cross_grad_e_C_vec_H[3], e_C_vec_cross_grad_j_C_vec_H[3]; - - cross3(j_A_vec, grad_j_A_vec_H, j_A_vec_cross_grad_j_A_vec_H); - cross3(j_A_vec, grad_e_A_vec_H, j_A_vec_cross_grad_e_A_vec_H); - cross3(j_B_vec, grad_j_B_vec_H, j_B_vec_cross_grad_j_B_vec_H); - cross3(j_B_vec, grad_e_B_vec_H, j_B_vec_cross_grad_e_B_vec_H); - cross3(j_C_vec, grad_j_C_vec_H, j_C_vec_cross_grad_j_C_vec_H); - cross3(j_C_vec, grad_e_C_vec_H, j_C_vec_cross_grad_e_C_vec_H); - - cross3(e_A_vec, grad_e_A_vec_H, e_A_vec_cross_grad_e_A_vec_H); - cross3(e_A_vec, grad_j_A_vec_H, e_A_vec_cross_grad_j_A_vec_H); - cross3(e_B_vec, grad_e_B_vec_H, e_B_vec_cross_grad_e_B_vec_H); - cross3(e_B_vec, grad_j_B_vec_H, e_B_vec_cross_grad_j_B_vec_H); - cross3(e_C_vec, grad_e_C_vec_H, e_C_vec_cross_grad_e_C_vec_H); - cross3(e_C_vec, grad_j_C_vec_H, e_C_vec_cross_grad_j_C_vec_H); - - for (int i=0; i<3; i++) - { - binary_A->de_vec_dt[i] += (-1.0/(Lambda_A))*( e_A_vec_cross_grad_j_A_vec_H[i] \ - + j_A_vec_cross_grad_e_A_vec_H[i] ); - binary_A->dh_vec_dt[i] += -1.0*( j_A_vec_cross_grad_j_A_vec_H[i] \ - + e_A_vec_cross_grad_e_A_vec_H[i] ); - - binary_B->de_vec_dt[i] += (-1.0/(Lambda_B))*( e_B_vec_cross_grad_j_B_vec_H[i] \ - + j_B_vec_cross_grad_e_B_vec_H[i] ); - binary_B->dh_vec_dt[i] += -1.0*( j_B_vec_cross_grad_j_B_vec_H[i] \ - + e_B_vec_cross_grad_e_B_vec_H[i] ); - - binary_C->de_vec_dt[i] += (-1.0/(Lambda_C))*( e_C_vec_cross_grad_j_C_vec_H[i] \ - + j_C_vec_cross_grad_e_C_vec_H[i] ); - binary_C->dh_vec_dt[i] += -1.0*( j_C_vec_cross_grad_j_C_vec_H[i] \ - + e_C_vec_cross_grad_e_C_vec_H[i] ); - } - - return binary_triplet_hamiltonian; -} - diff --git a/src/amuse/community/secularmultiple/src/newtonian.h b/src/amuse/community/secularmultiple/src/newtonian.h deleted file mode 100644 index 0bf4700388..0000000000 --- a/src/amuse/community/secularmultiple/src/newtonian.h +++ /dev/null @@ -1,6 +0,0 @@ -#include "types.h" - -double compute_orbital_period(Particle *particle); - -double compute_EOM_binary_pairs(ParticlesMap *particlesMap, int inner_binary_index, int outer_binary_index, int connecting_child_in_outer_binary, bool compute_hamiltonian_only); -double compute_EOM_binary_triplets(ParticlesMap *particlesMap, int binary_A_index, int binary_B_index, int binary_C_index, int connecting_child_in_binary_B_to_binary_A, int connecting_child_in_binary_C_to_binary_B, bool compute_hamiltonian_only); diff --git a/src/amuse/community/secularmultiple/src/postnewtonian.cpp b/src/amuse/community/secularmultiple/src/postnewtonian.cpp deleted file mode 100644 index 1fecaed243..0000000000 --- a/src/amuse/community/secularmultiple/src/postnewtonian.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* -*/ - -#include "types.h" -#include "postnewtonian.h" -#include - -double compute_EOM_pairwise_1PN(ParticlesMap *particlesMap, int binary_index, bool compute_hamiltonian_only) -{ -// printf("compute_EOM_pairwise_1PN\n"); - Particle *binary = (*particlesMap)[binary_index]; - double e = binary->e; - double a = binary->a; - double *e_vec_unit = binary->e_vec_unit; - double *h_vec_unit = binary->h_vec_unit; - double j = binary->j; - double j_p2 = binary->j_p2; - double m1 = binary->child1_mass; - double m2 = binary->child2_mass; - double mt = m1+m2; - - double hamiltonian_1PN = -3.0*CONST_G_P2*m1*m2*mt/(a*a*CONST_C_LIGHT_P2*j); - if (compute_hamiltonian_only == true) - { - return hamiltonian_1PN; - } - - double q_vec_unit[3]; - cross3(h_vec_unit,e_vec_unit,q_vec_unit); - - double GMdiva = CONST_G*mt/a; - double Z_1PN = 3.0*sqrt(GMdiva)*GMdiva/(a*CONST_C_LIGHT_P2*j_p2); - for (int i=0; i<3; i++) - { - binary->de_vec_dt[i] += e*Z_1PN*q_vec_unit[i]; - } - - return hamiltonian_1PN; -} - -double compute_EOM_pairwise_25PN(ParticlesMap *particlesMap, int binary_index, bool compute_hamiltonian_only) -{ - Particle *binary = (*particlesMap)[binary_index]; - double e = binary->e; - double e_p2 = e*e; - double a = binary->a; - double *e_vec_unit = binary->e_vec_unit; - double *h_vec_unit = binary->h_vec_unit; - double j = binary->j; - double j_p2 = binary->j_p2; - double j_p4 = binary->j_p4; - double m1 = binary->child1_mass; - double m2 = binary->child2_mass; - double mt = m1+m2; - - double a_p3 = a*a*a; - double GMdiva = CONST_G*mt/a; - double c_common = CONST_G_P3*m1*m2/(CONST_C_LIGHT_P5*a_p3*j_p4); - double f_e = 1.0 + c_121div304*e_p2; - double f_h = 1.0 + c_7div8*e_p2; - - double de_dt = -c_304div15*c_common*mt*e*f_e/(a*j); - double dh_dt = -c_32div5*c_common*m1*m2*sqrt(GMdiva)*f_h; - - for (int i=0; i<3; i++) - { - binary->de_vec_dt[i] += de_dt*e_vec_unit[i]; - binary->dh_vec_dt[i] += dh_dt*h_vec_unit[i]; - } - - return 0.0; // N/A -} diff --git a/src/amuse/community/secularmultiple/src/postnewtonian.h b/src/amuse/community/secularmultiple/src/postnewtonian.h deleted file mode 100644 index 5e489105e4..0000000000 --- a/src/amuse/community/secularmultiple/src/postnewtonian.h +++ /dev/null @@ -1,4 +0,0 @@ -#include "types.h" - -double compute_EOM_pairwise_1PN(ParticlesMap *particlesMap, int binary_index, bool compute_hamiltonian_only); -double compute_EOM_pairwise_25PN(ParticlesMap *particlesMap, int binary_index, bool compute_hamiltonian_only); diff --git a/src/amuse/community/secularmultiple/src/root_finding.cpp b/src/amuse/community/secularmultiple/src/root_finding.cpp deleted file mode 100644 index 332433a2a2..0000000000 --- a/src/amuse/community/secularmultiple/src/root_finding.cpp +++ /dev/null @@ -1,505 +0,0 @@ -/* -*/ - -#include "types.h" -#include "evolve.h" -#include "root_finding.h" -#include - - -int root_finding_functions(realtype time, N_Vector y, realtype *root_functions, void *data_) -{ - - UserData data; - data = (UserData) data_; - ParticlesMap *particlesMap = data->particlesMap; - int N_root_finding = data->N_root_finding; - double start_time = data->start_time; - double delta_time = time - start_time; - - extract_ODE_variables(particlesMap, y, delta_time, false); // do not reset ODE quantities - - double large_quantity = 1.0e10; - for (int i=0; i::iterator it_parent; - - int i_root = 0; - - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - if (P_p->is_binary == 1) - { - if (P_p->check_for_secular_breakdown == 1) - { - double hamiltonian=0.0; - for (it_parent = P_p->parents.begin(); it_parent != P_p->parents.end(); it_parent++) - { - int i = std::distance(P_p->parents.begin(), it_parent); - Particle *P_q = (*particlesMap)[(*it_parent)]; - int connecting_child_in_parent = P_p->connecting_child_in_parents[i]; - hamiltonian += compute_EOM_binary_pairs(particlesMap,P_p->index,P_q->index,connecting_child_in_parent,false); - } - - double AM_time_scale = compute_AM_time_scale(P_p); - double orbital_period = compute_orbital_period(P_p); - root_functions[i_root] = 1.0 - AM_time_scale/orbital_period; - //printf("sb %g\n",root_functions[i_root]); - - i_root++; - } - - if (P_p->check_for_dynamical_instability == 1) - { - if (P_p->parent != -1) - { - Particle *P_parent = (*particlesMap)[P_p->parent]; - Particle *P_child1 = (*particlesMap)[P_p->child1]; - Particle *P_child2 = (*particlesMap)[P_p->child2]; - - double a_out = P_parent->a; - double e_out = P_parent->e; - double a_in = P_p->a; - double e_in = P_p->e; - double M_p = P_p->mass; - double ra_in = a_in*(1.0+e_in); - double rp_out = a_out*(1.0-e_out); - -// printf("check_for_dynamical_instability p %d par %d c1 %d c2 %d \n",P_p->index,P_parent->index,P_child1->index,P_child2->index); -// printf("a_in %g a_out %g\n",a_in,a_out); - - Particle *P_sibling = (*particlesMap)[P_p->sibling]; - - if (P_p->dynamical_instability_criterion == 0) /* for mass ratios on the order of unity */ - { - /* Mardling & Aarseth 2001 */ - double q_out = P_sibling->mass/M_p; - double rel_INCL = 0.0; - get_inclination_relative_to_parent(P_p->index,&rel_INCL); - root_functions[i_root] = rp_out - a_in*2.8*pow( (1.0+q_out)*(1.0+e_out)/sqrt(1.0-e_out),2.0/5.0)*(1.0 - 0.3*rel_INCL/M_PI); - //printf("di MA %g\n",root_functions[i_root]); - //printf("di MA %g %g\n",P_sibling->mass,M_p); - } - if (P_p->dynamical_instability_criterion == 1) /* for S-type test particles in binaries */ - { - /* Wiegert & Holman 1999 */ - double m1 = M_p; - double m2 = P_sibling->mass; - double mu = m2/(m1+m2); - double e = e_out; - root_functions[i_root] = (0.464 - 0.38*mu - 0.631*e + 0.586*mu*e + 0.15*e*e - 0.198*mu*e*e) - a_in/a_out; - //printf("di WH %g %g %g %g %g %g\n",root_functions[i_root],m1,m2,e,a_in/a_out,(0.464 - 0.38*mu - 0.631*e + 0.586*mu*e + 0.15*e*e - 0.198*mu*e*e)); - - - //printf("di MA %g %g\n",P_sibling->mass,M_p); - } - else if (P_p->dynamical_instability_criterion > 1) - /* in case of a central dominant particle - * m1 is the `inner' mass; m2 is the `outer' mass */ - { - int central_particle_index = P_p->dynamical_instability_central_particle; - Particle *P_central_particle = (*particlesMap)[central_particle_index]; - double central_particle_mass = P_central_particle->mass; - double m2 = P_sibling->mass; - double m1; - if (P_p->child1 == central_particle_index) - { - m1 = P_child2->mass; - } - else if (P_p->child2 == central_particle_index) - { - m1 = P_child1->mass; - } - - int central_particle_parent; - std::vector::iterator it_C_parent; - for (it_C_parent = P_central_particle->parents.begin(); it_C_parent != P_central_particle->parents.end(); it_C_parent++) - { - central_particle_parent = *it_C_parent; - if (P_p->child1 == central_particle_parent) - { - m1 = P_child2->mass; - } - else if (P_p->child2 == central_particle_parent) - { - m1 = P_child1->mass; - } - } - -// else /* the central particle is not a direct child of P_p */ -// { -// if (P_child1->is_binary == true) -// { -// m1 = P_child2->mass; -// } -// else if (P_child2->is_binary == true) -// { -// m1 = P_child1->mass; -// } -// else -// { -// printf("error in root finding function dynamical_stability_criterion > 0: the system should be `fully nested'; exiting\n"); -// exit(-1); -// } - - double mu1 = m1/central_particle_mass; - double mu2 = m2/central_particle_mass; - double R_H = c_1div2*(a_in+a_out)*pow( c_1div3*(mu1+mu2), c_1div3 ); - - if (P_p->dynamical_instability_criterion == 2) - { - double K = P_p->dynamical_instability_K_parameter; - root_functions[i_root] = (rp_out - ra_in) - K*R_H; - //printf("rf %g %g %g %g %g\n",central_particle_mass,m1,m2,K,root_functions[i_root]); - } - - else if (P_p->dynamical_instability_criterion == 3) - /* Petrovich 2015 */ - { - root_functions[i_root] = rp_out/ra_in - ( 2.4*pow( max(mu1,mu2), c_1div3)*sqrt(a_out/a_in) + 1.15 ); - } - - } - - if (root_functions[i_root] <= 0.0) - { - P_p->dynamical_instability_has_occurred = 1; -// printf("stop\n"); - } - - //printf("di P15a %d %d %g %g %g\n",P_p->index,central_particle_index,m1,m2,central_particle_mass); - //printf("di P15b %g %g %g \n",a_in,a_out,root_functions[i_root]); - - } - i_root++; - } - if (P_p->check_for_physical_collision_or_orbit_crossing == 1) - { - Particle *P_child1 = (*particlesMap)[P_p->child1]; - Particle *P_child2 = (*particlesMap)[P_p->child2]; - - double cross_section = 0.0; - cross_section_function(P_child1,&cross_section); - cross_section_function(P_child2,&cross_section); - - double periapse_distance = P_p->a*(1.0 - P_p->e); - root_functions[i_root] = 1.0 - periapse_distance/cross_section; - -// printf("root finding check_for_physical_collision_or_orbit_crossing %d %g %g %g\n",P_p->index,P_p->a,cross_section, root_functions[i_root]); - if (root_functions[i_root] >= 0.0) - { - P_p->physical_collision_or_orbit_crossing_has_occurred = 1; -// printf("root finding check_for_physical_collision_or_orbit_crossing %d %g %g %g\n",P_p->index,P_p->a,cross_section, root_functions[i_root]); - } - - i_root++; - } - if (P_p->check_for_minimum_periapse_distance == 1) - { - Particle *P_child1 = (*particlesMap)[P_p->child1]; - Particle *P_child2 = (*particlesMap)[P_p->child2]; - - double cross_section = P_p->check_for_minimum_periapse_distance_value; - double periapse_distance = P_p->a*(1.0 - P_p->e); - root_functions[i_root] = 1.0 - periapse_distance/cross_section; - -// printf("root finding check_for_minimum_periapse_distance %d %g %g %g\n",P_p->index,P_p->a,cross_section, root_functions[i_root]); - if (root_functions[i_root] >= 0.0) - { - P_p->minimum_periapse_distance_has_occurred = 1; -// printf("root finding check_for_minimum_periapse_distance %d %g %g %g\n",P_p->index,P_p->a,cross_section, root_functions[i_root]); - } - - i_root++; - } - } - else /* P_p not a binary */ - { - - if (P_p->check_for_RLOF_at_pericentre == 1) - { - if (P_p->parent != -1) - { - Particle *P_parent = (*particlesMap)[P_p->parent]; - Particle *P_sibling = (*particlesMap)[P_p->sibling]; - - double a = P_parent->a; - double e = P_parent->e; - double rp = a*(1.0 - e); - double subject_mass = P_p->mass; - double companion_mass = P_sibling->mass; - - double spin_angular_frequency = P_p->spin_vec_norm; - double orbital_angular_frequency_periapse = sqrt( CONST_G*(subject_mass + companion_mass)*(1.0 + e)/(rp*rp*rp) ); - double f = spin_angular_frequency/orbital_angular_frequency_periapse; - - double roche_radius_pericenter; - if (P_p->check_for_RLOF_at_pericentre_use_sepinsky_fit == 0) - { - roche_radius_pericenter = roche_radius_pericenter_eggleton(rp, subject_mass/companion_mass); - } - else - { - roche_radius_pericenter = roche_radius_pericenter_sepinsky(rp, subject_mass/companion_mass, e, f); - } - - root_functions[i_root] = 1.0 - P_p->radius/roche_radius_pericenter; -// printf("check_for_RLOF_at_pericentre rp %g roche_radius_pericenter %g R %g\n", rp, roche_radius_pericenter, P_p->radius); - - if (root_functions[i_root] <= 0.0) - { - P_p->RLOF_at_pericentre_has_occurred = 1; - } - } - - i_root++; - } - } - } - return 0; -} - -void cross_section_function(Particle *p, double *cross_section) -{ - if (p->is_binary==0) - { - *cross_section += p->radius; - } - else - { - *cross_section += p->a*(1.0 + p->e); - } -} -double compute_AM_time_scale(Particle *P_p) -{ - double e = P_p->e; - double e_p2 = P_p->e_p2; - double de_dt = dot3(P_p->e_vec_unit,P_p->de_vec_dt); - double AM_time_scale = ((1.0-e_p2)/(e*fabs(de_dt))); - - return AM_time_scale; -} - - -double roche_radius_pericenter_eggleton(double rp, double q) -{ - /* 2007ApJ...660.1624S Eqs. (45) */ - /* q is defined as m_primary/m_secondary */ - double q_pow_one_third = pow(q,c_1div3); - double q_pow_two_third = q_pow_one_third*q_pow_one_third; - return rp*0.49*q_pow_two_third/(0.6*q_pow_two_third + log(1.0 + q_pow_one_third)); -} -double roche_radius_pericenter_sepinsky(double rp, double q, double e, double f) -{ - /* 2007ApJ...660.1624S Eqs. (47)-(52) */ - double log_q = log10(q); - double A = f*f*(1.0 + e); // assumes pericenter - double log_A = log10(A); - - double R_L_pericenter_eggleton = roche_radius_pericenter_eggleton(rp,q); - double ratio = 0.0; // this is R_L divided by R_L_pericenter_eggleton - - if (log_q < 0.0) - { - if (log_A <= -0.1) - { - double c = 0.5*(1.0+A) + log_q; - ratio = 1.0 + 0.11*(1.0-A) - 0.05*(1.0-A)*exp(-c*c); - } - if ((log_A > -0.1) && (log_A < 0.2)) - { - double g_0 = 0.9978 - 0.1229*log_A - 0.1273*log_A*log_A; - double g_1 = 0.001 + 0.02556*log_A; - double g_2 = 0.0004 + 0.0021*log_A; - ratio = g_0 + g_1*log_q * g_2*log_q*log_q; - } - if (log_A >= 0.2) - { - double num_0 = 6.3014*pow(log_A,1.3643); - double den_0 = exp(2.3644*pow(log_A,0.70748)) - 1.4413*exp(-0.0000184*pow(log_A,-4.5693)); - double i_0 = num_0/den_0; - - double den_1 = 0.0015*exp(8.84*pow(log_A,0.282)) + 15.78; - double i_1 = log_A/den_1; - - double num_2 = 1.0 + 0.036*exp(8.01*pow(log_A,0.879)); - double den_2 = 0.105*exp(7.91*pow(log_A,0.879)); - double i_2 = num_2/den_2; - - double den_3 = 1.38*exp(-0.035*pow(log_A,0.76)) + 23.0*exp(-2.89*pow(log_A,0.76)); - double i_3 = 0.991/den_3; - - double c = log_q + i_3; - ratio = i_0 + i_1*exp(-i_2*c*c); - } - } - if (log_q >= 0.0) - { - if (log_A <= -0.1) - { - ratio = 1.226 - 0.21*A - 0.15*(1.0-A)*exp( (0.25*A - 0.3)*pow(log_q,1.55) ); - } - if ((log_A > -0.1) && (log_A < 0.2)) - { - double log_A_p2 = log_A*log_A; - double h_0 = 1.0071 - 0.0907*log_A - 0.0495*log_A_p2; - double h_1 = -0.004 - 0.163*log_A - 0.214*log_A_p2; - double h_2 = 0.00022 - 0.0108*log_A - 0.02718*log_A_p2; - ratio = h_0 + h_1*log_q + h_2*log_q*log_q; - } - if (log_A >= 0.2) - { - double num_0 = 1.895*pow(log_A,0.837); - double den_0 = exp(1.636*pow(log_A,0.789)) - 1.0; - double j_0 = num_0/den_0; - - double num_1 = 4.3*pow(log_A,0.98); - double den_1 = exp(2.5*pow(log_A,0.66)) + 4.7; - double j_1 = num_1/den_1; - - double den_2 = 8.8*exp(-2.95*pow(log_A,0.76)) + 1.64*exp(-0.03*pow(log_A,0.76)); - double j_2 = 1.0/den_2; - -// double j_3 = 0.256*exp(-1.33*pow(log_A,2.9))*( 5.5*exp(1.33*pow(log_A,2.9)) + 1.0 ); - double j_3 = 0.256*(5.5 + exp(-1.33*pow(log_A,2.9))); - - ratio = j_0 + j_1*exp(-j_2*pow(log_q,j_3)); - -// printf("log_A %g\n",log_A); -// printf("1 %g %g %g \n",num_0,den_0,j_0); -// printf("2 %g %g %g \n",num_1,den_1,j_1); -// printf("2 %g %g %g \n",den_2,j_2,j_3); -// printf("ratio %g %g %g \n",ratio); - } - } - - if (ratio == 0.0) - { - printf("unrecoverable error occurred in function roche_radius_pericenter_sepinsky in ODE_system.cpp\n"); - printf("log_q %g log_A %g ratio %g\n",log_q,log_A,ratio); - printf("rp %g q %g e %g f %g\n",rp,q,e,f); - exit(-1); - } - - return ratio*R_L_pericenter_eggleton; -} - -int read_root_finding_data(ParticlesMap *particlesMap, int *roots_found) -{ - ParticlesMapIterator it_p; - - int i_root = 0; - - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - if (P_p->is_binary == 1) - { - if (P_p->check_for_secular_breakdown == 1) - { - if FOUND_ROOT - { - P_p->secular_breakdown_has_occurred = 1; - } - i_root++; - - } - if (P_p->check_for_dynamical_instability == 1) - { - if FOUND_ROOT - { - P_p->dynamical_instability_has_occurred = 1; - } - i_root++; - } - if (P_p->check_for_physical_collision_or_orbit_crossing == 1) - { - if FOUND_ROOT - { - P_p->physical_collision_or_orbit_crossing_has_occurred = 1; - } - i_root++; - } - if (P_p->check_for_minimum_periapse_distance == 1) - { - if FOUND_ROOT - { - P_p->minimum_periapse_distance_has_occurred = 1; - } - i_root++; - } - } - else /* P_p not a binary */ - { - if (P_p->check_for_RLOF_at_pericentre == 1) - { - if FOUND_ROOT - { - P_p->RLOF_at_pericentre_has_occurred = 1; - } - i_root++; - } - } - } - return 0; -} - -int check_for_initial_roots(ParticlesMap *particlesMap) -{ - ParticlesMapIterator it_p; - - int N_root_found = 0; - - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - if (P_p->is_binary == 1) - { - if (P_p->check_for_secular_breakdown == 1) - { - if (P_p->secular_breakdown_has_occurred == 1) - { - N_root_found++; - } - - } - if (P_p->check_for_dynamical_instability == 1) - { - if (P_p->dynamical_instability_has_occurred == 1) - { - N_root_found++; - } - } - if (P_p->check_for_physical_collision_or_orbit_crossing == 1) - { - if (P_p->physical_collision_or_orbit_crossing_has_occurred == 1) - { - N_root_found++; - } - } - if (P_p->check_for_minimum_periapse_distance == 1) - { - if (P_p->minimum_periapse_distance_has_occurred == 1) - { - N_root_found++; - } - } - } - else /* P_p not a binary */ - { - if (P_p->check_for_RLOF_at_pericentre == 1) - { - if (P_p->RLOF_at_pericentre_has_occurred == 1) - { - N_root_found++; - } - } - } - } - return N_root_found; -} diff --git a/src/amuse/community/secularmultiple/src/root_finding.h b/src/amuse/community/secularmultiple/src/root_finding.h deleted file mode 100644 index b36c6ea161..0000000000 --- a/src/amuse/community/secularmultiple/src/root_finding.h +++ /dev/null @@ -1,11 +0,0 @@ -#include "types.h" - -double compute_AM_time_scale(Particle *P_p); -void cross_section_function(Particle *p,double *cross_section); - -int root_finding_functions(realtype t, N_Vector y, realtype *root_functions, void *data_); -double roche_radius_pericenter_eggleton(double rp, double q); -double roche_radius_pericenter_sepinsky(double rp, double q, double e, double f); - -int read_root_finding_data(ParticlesMap *particlesMap, int *roots_found); -int check_for_initial_roots(ParticlesMap *particlesMap); diff --git a/src/amuse/community/secularmultiple/src/structure.cpp b/src/amuse/community/secularmultiple/src/structure.cpp deleted file mode 100644 index 8273afc3b2..0000000000 --- a/src/amuse/community/secularmultiple/src/structure.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* -*/ - -#include "types.h" -#include "structure.h" -#include - - -void determine_binary_parents_and_levels(ParticlesMap *particlesMap, int *N_bodies, int *N_binaries, int *N_root_finding) -{ - *N_bodies = 0; - *N_binaries = 0; - *N_root_finding = 0; - - /* determine parent for each particle */ - ParticlesMapIterator it_p,it_q; - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - - P_p->parent = -1; - - if (P_p->is_binary == 1) - { - (*N_binaries)++; - - /* root finding */ - if (P_p->check_for_secular_breakdown == 1) - { - (*N_root_finding)++; - } - if (P_p->check_for_dynamical_instability == 1) - { - (*N_root_finding)++; - } - if (P_p->check_for_physical_collision_or_orbit_crossing == 1) - { - (*N_root_finding)++; - } - if (P_p->check_for_minimum_periapse_distance == 1) - { - (*N_root_finding)++; - } - - /* parents and siblings */ - for (it_q = particlesMap->begin(); it_q != particlesMap->end(); it_q++) - { - Particle *P_q = (*it_q).second; - -// if ((P_q->index == P_p->child1) || (P_q->index == P_p->child2)) -// { -// P_q->parent = P_p->index; -// } - if (P_q->index == P_p->child1) - { - P_q->parent = P_p->index; - P_q->sibling = P_p->child2; - } - if (P_q->index == P_p->child2) - { - P_q->parent = P_p->index; - P_q->sibling = P_p->child1; - } - } - } - else - { - (*N_bodies)++; - - /* root finding */ - if (P_p->check_for_RLOF_at_pericentre == 1) - { - (*N_root_finding)++; - } - - } - } - - /* determine levels and set of parents for each particle */ - int highest_level = 0; - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - - P_p->connecting_child_in_parents.clear(); - P_p->parents.clear(); - P_p->level=0; - - int child = P_p->index; - int parent = P_p->parent; - - if (parent != -1) /* if parent == -1, P_p is the `top' binary, for which level=0 */ - { - while (parent != -1) /* search parents until reaching the top binary */ - { - for (it_q = particlesMap->begin(); it_q != particlesMap->end(); it_q++) - { - Particle *P_q = (*it_q).second; - if (P_q->index == parent) - { - if (child==P_q->child1) - { - P_p->connecting_child_in_parents.push_back(1); - } - else if (child==P_q->child2) - { - P_p->connecting_child_in_parents.push_back(2); - } - P_p->parents.push_back(parent); - P_p->level++; - - child = P_q->index; - parent = P_q->parent; -// printf("p %d q %d %d child %d\n",P_p->index,P_q->index,P_p->level,child); - break; - } - } - } - } - highest_level = max(P_p->level,highest_level); -// printf("hl %d %d\n",P_p->level,highest_level); -// std::vector::iterator it; -// for (it = P_p->parents.begin(); it != P_p->parents.end(); it++) -// { -// printf("test %d %d\n",P_p->index,*it); -// } - } - - /* write highest level to all particles -- needed for function set_binary_masses_from_body_masses */ - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - - P_p->highest_level = highest_level; - } - - -// for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) -// { -// Particle *P_p = (*it_p).second; -// printf("particle %d mass %g e_vec_x %g h_vec_x %g\n",P_p->index,P_p->mass,P_p->e_vec_x,P_p->h_vec_x); -// } -} - -void set_binary_masses_from_body_masses(ParticlesMap *particlesMap) -{ - /* set binary masses -- to ensure this happens correctly, do this from highest level to lowest level */ - ParticlesMapIterator it_p; - int highest_level = (*particlesMap)[0]->highest_level; - int level=highest_level; - while (level > -1) - { - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - if ((P_p->is_binary == 1) && (P_p->level == level)) - { - Particle *P_p_child1 = (*particlesMap)[P_p->child1]; - Particle *P_p_child2 = (*particlesMap)[P_p->child2]; - - /* these quantities are used in ODE_system.cpp */ - P_p->child1_mass = P_p_child1->mass; - P_p->child2_mass = P_p_child2->mass; - P_p->mass = P_p->child1_mass + P_p->child2_mass; - - P_p->child1_mass_dot_external = P_p_child1->mass_dot_external; - P_p->child2_mass_dot_external = P_p_child2->mass_dot_external; - P_p->mass_dot_external = P_p->child1_mass_dot_external + P_p->child2_mass_dot_external; - - P_p->child1_mass_plus_child2_mass = P_p->child1_mass + P_p->child2_mass; - P_p->child1_mass_minus_child2_mass = P_p->child1_mass - P_p->child2_mass; - P_p->child1_mass_times_child2_mass = P_p->child1_mass*P_p->child2_mass; - -// printf("level %d m %g hl %d\n",level,P_p->mass,highest_level); - } - } - level--; - } - - /* determine total system mass -- needed for hyperbolic external orbits */ - double total_system_mass; - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - if (P_p->level==0) /* lowest-level binary */ - { - total_system_mass = P_p->child1_mass + P_p->child2_mass; - break; - } - } - - for (it_p = particlesMap->begin(); it_p != particlesMap->end(); it_p++) - { - Particle *P_p = (*it_p).second; - - P_p->total_system_mass = total_system_mass; - } - -} diff --git a/src/amuse/community/secularmultiple/src/structure.h b/src/amuse/community/secularmultiple/src/structure.h deleted file mode 100644 index 8dce1242c8..0000000000 --- a/src/amuse/community/secularmultiple/src/structure.h +++ /dev/null @@ -1,4 +0,0 @@ -#include "types.h" - -void determine_binary_parents_and_levels(ParticlesMap *particlesMap, int *N_bodies, int *N_binaries, int *N_root_finding); -void set_binary_masses_from_body_masses(ParticlesMap *particlesMap); diff --git a/src/amuse/community/secularmultiple/src/tides.cpp b/src/amuse/community/secularmultiple/src/tides.cpp deleted file mode 100644 index d4e94de0ff..0000000000 --- a/src/amuse/community/secularmultiple/src/tides.cpp +++ /dev/null @@ -1,624 +0,0 @@ -/* -*/ - -#include "types.h" -#include "tides.h" -#include "newtonian.h" /* for orbital_period */ -#include - -double const MINIMUM_MASS_FOR_RADIATIVE_DAMPING_MSUN = 1.2; // in future: make user-adjustable -int const MAIN_SEQUENCE = 1; -int const CHeB = 4; -int const HeMS = 7; -int const HeWD = 10; - -/* start addition 13-09-2016 */ -int const PreMS = 17; -/* end addition 13-09-2016 */ - -bool check_for_radiative_damping(int stellar_type, double mass, double convective_envelope_mass, double convective_envelope_radius) -{ - if ((stellar_type == MAIN_SEQUENCE) && (mass/CONST_MSUN >= MINIMUM_MASS_FOR_RADIATIVE_DAMPING_MSUN)) - { - return true; - } - else if ((stellar_type == CHeB) || (stellar_type == HeMS)) - { - return true; - } - else - { - return false; - } -} -bool check_for_convective_damping(int stellar_type) -{ - /* start addition 13-09-2016 */ - if (stellar_type == PreMS) - { - return true; - } - /* end addition 13-09-2016 */ - - if (stellar_type < HeWD) - { - return true; - } - else - { - return false; - } -} - -double from_k_AM_div_T_to_t_V(double k_AM_div_T, double apsidal_motion_constant) -{ - return c_3div2*(2.0*apsidal_motion_constant + 1.0)/k_AM_div_T; -} - -double compute_t_V(Particle *star, Particle *companion, double semimajor_axis) -{ - int tides_viscous_time_scale_prescription = star->tides_viscous_time_scale_prescription; - double t_V = 1.0e10; /* large value by default, i.e. weak tides if tides_viscous_time_scale_prescription is not given the correct value */ - - if (tides_viscous_time_scale_prescription == 0) - { - t_V = star->tides_viscous_time_scale; - } - else if (tides_viscous_time_scale_prescription == 1) - { - t_V = compute_t_V_hurley - ( - star->stellar_type, - star->mass, - star->convective_envelope_mass, - companion->mass, - semimajor_axis, - star->radius, - star->convective_envelope_radius, - star->luminosity, - star->spin_vec_norm, - star->tides_gyration_radius, - star->tides_apsidal_motion_constant - ); - } - - return t_V; -} - -double compute_t_V_hurley -( - int stellar_type, - double mass, - double convective_envelope_mass, - double companion_mass, - double semimajor_axis, - double radius, - double convective_envelope_radius, - double luminosity, - double spin_angular_frequency, - double gyration_radius, - double apsidal_motion_constant -) -{ - bool USE_RADIATIVE_DAMPING = check_for_radiative_damping(stellar_type,mass,convective_envelope_mass,convective_envelope_radius); - bool USE_CONVECTIVE_DAMPING = check_for_convective_damping(stellar_type); - double k_AM_div_T,t_V; - - if (USE_CONVECTIVE_DAMPING == true && ((convective_envelope_mass <= 0.0) || (convective_envelope_radius <= 0.0))) - { - //printf("to rad \n"); - USE_RADIATIVE_DAMPING = true; - } - if (radius <= 0.0) - { - return 1.0e100; - } - - //printf("stellar_type %d \n",stellar_type); - //printf("USE_RADIATIVE_DAMPING %d \n",USE_RADIATIVE_DAMPING); - //printf("USE_CONVECTIVE_DAMPING %d \n",USE_CONVECTIVE_DAMPING); - - if (USE_RADIATIVE_DAMPING == true) // radiative damping - { - double E2 = 1.592e-09*pow(mass/CONST_MSUN,2.84); // Hurley prescription; Zahn, 1977, A&A, 57, 383 and 1975, A&A, 41, 329 - -#ifdef IGNORE - // Izzard's prescription not yet implemented - else if(stardata->preferences->E2_prescription==E2_IZZARD) - { - if(stardata->star[star_number].stellar_typestar[star_number].aj/stardata->star[star_number].tms; - if(xstar[star_number].mass); - double logz=log10(stardata->common.metallicity); - - /* fits for am and E20 */ - double am = 0.15*sin(3.2*logm)+0.31*logm; - double E20 = -1.23250e+01+1.04550e+01*logm-4.15420e-01*logz-7.18650e+00*logm*logm+1.97940e+00*logm*logm*logm; - E20=pow(10.0,E20); - - /* calc log(E2/E20) */ - E2 = -pow(x+am,4.0)*pow(MAX(1,x/0.95),30.0); - - /* hence E2 */ - E2 = E20 * pow(10.0,E2); - - /* verbosity */ - /* - if(star->starnum==1) - { - printf("E2 kw=%d I=%g (fburn=%g x=%g E20=%g) H=%g\n", - star->stellar_type, - E2, - fburn,x, - E20,E2_Hurley); - } - */ - } - else - { - /* no conv core */ - E2=0.0; - } - } - else - { - E2=0.0; - } - } -#endif - - k_AM_div_T = E2*pow(1.0 + companion_mass/mass,5.0/6.0)*radius*sqrt(CONST_G*mass/(pow(semimajor_axis,5.0))); - t_V = from_k_AM_div_T_to_t_V(k_AM_div_T,apsidal_motion_constant); - return t_V; - - } - else if (USE_CONVECTIVE_DAMPING == true) // convective damping - { - double P_orb = 2.0*M_PI*sqrt((semimajor_axis*semimajor_axis*semimajor_axis)/(CONST_G*(mass + companion_mass))); -// printf("a %g\n",semimajor_axis); - double P_spin,P_tid; - - if (spin_angular_frequency == 0.0) - { - P_tid = P_orb; - } - else - { - P_spin = 2.0*M_PI/spin_angular_frequency; - P_tid = 1.0/( 1e-10 + fabs( 1.0/P_orb - 1.0/P_spin) ); - } - - double tau_convective = pow( (convective_envelope_mass*convective_envelope_radius*(radius - (1.0/2.0)*convective_envelope_radius))/(3.0*luminosity), 1.0/3.0); - //double tau_convective = pow( (convective_envelope_mass*radius*radius)/(3.0*luminosity), 1.0/3.0); -// print 'tau',envelope_mass,envelope_mass*envelope_radius*(radius - (1.0/2.0)*envelope_radius)/(3.0*luminosity) - - double f_convective = pow(P_tid/(2.0*tau_convective),2.0); - f_convective = min(1.0,f_convective); - - k_AM_div_T = (2.0/21.0)*(f_convective/tau_convective)*(convective_envelope_mass/mass); - t_V = from_k_AM_div_T_to_t_V(k_AM_div_T,apsidal_motion_constant); - - //printf("test %g %g %g %g %g %g %g \n",P_spin,P_tid,P_orb,tau_convective,f_convective,k_AM_div_T,t_V); - - //if ((convective_envelope_mass <= 0.0) || (convective_envelope_radius <= 0.0)) - // { - // t_V = 1.0e100; - // } - -// printf("test par conv %g %g %g %g %g \n",mass,radius,convective_envelope_mass,convective_envelope_radius,spin_angular_frequency); -// printf("test conv %g %g %g %g %g \n",P_orb,tau_convective,P_tid,P_spin,f_convective); - return t_V; - - } - else // degenerate damping -- 1984MNRAS.207..433C - { - double seconds_in_year = 365.25*24.0*3600.0; - double tau_degenerate = 1.3e7*seconds_in_year; - k_AM_div_T = (1.0/(3.0*tau_degenerate))*gyration_radius*gyration_radius*pow((luminosity/CONST_L_SUN)/(mass/CONST_MSUN),5.0/7.0); - t_V = from_k_AM_div_T_to_t_V(k_AM_div_T,apsidal_motion_constant); - - return t_V; - } -} - -double compute_EOM_equilibrium_tide_BO_full(ParticlesMap *particlesMap, int binary_index, int star_index, int companion_index, int include_tidal_friction_terms, int include_tidal_bulges_precession_terms, int include_rotation_precession_terms, double minimum_eccentricity_for_tidal_precession, int tides_method) -/* Barker & Ogilvie (2009; http://adsabs.harvard.edu/abs/2009MNRAS.395.2268B) */ - -/* NOTE: in SecularMultiple, the h-vector is defined as the orbital angular momentum vector, - * NOT the SPECIFIC orbital angular momentum vector. Compared to the notation used by Eggleton, - * h_vec_SecularMultiple = mu*h_vec_Eggleton where mu = m*M/(m+M) is the reduced mass. - * In particular, note the line `star->dspin_vec_dt[i] += -dh_vec_dt_star[i]/I;' */ -{ -// printf("tides BO full\n"); -// printf("TIDES %d %d %d\n",binary_index,star_index,companion_index); - Particle *binary = (*particlesMap)[binary_index]; - Particle *star = (*particlesMap)[star_index]; - Particle *companion = (*particlesMap)[companion_index]; - - /* orbit quantities */ - double e = binary->e; - double e_p2 = binary->e_p2; - double a = binary->a; - double h = binary->h; - double *e_vec = binary->e_vec; - double *h_vec = binary->h_vec; - double *e_vec_unit = binary->e_vec_unit; - double *h_vec_unit = binary->h_vec_unit; - double j = binary->j; - double j_p2 = binary->j_p2; - double j_p3 = binary->j_p3; - double j_p4 = binary->j_p4; - double j_p8 = j_p4*j_p4; - double j_p10 = j_p2*j_p8; - double j_p13 = j_p3*j_p10; - double j_p4_inv = 1.0/j_p4; - double j_p10_inv = 1.0/j_p10; - double j_p13_inv = 1.0/j_p13; - double P_orb = compute_orbital_period(binary); - double n = 2.0*M_PI/P_orb; /* mean motion */ - - /* stellar properties */ - double *spin_vec = star->spin_vec; - double M = star->mass; - double m = companion->mass; - double R = star->radius; - double k_AM = star->tides_apsidal_motion_constant; - double rg = star->tides_gyration_radius; - - double t_V = compute_t_V(star,companion,a); - star->tides_viscous_time_scale = t_V; - - if (t_V!=t_V) - { - printf("ERRORRRR\n"); - printf("t_V %g \n",t_V); - printf("st %d\n",star->stellar_type); - printf("pr %d\n",star->tides_viscous_time_scale_prescription); - printf("M %g\n",M); - printf("star->convective_envelope_mass %g\n",star->convective_envelope_mass); - printf("m %g\n",m); - printf("a %g\n",a); - printf("R %g\n",R); - printf("star->convective_envelope_radius %g\n",star->convective_envelope_radius); - printf("star->luminosity %g\n",star->luminosity); - } - if (1==0) - { - printf("t_V %g \n",t_V); - printf("st %d\n",star->stellar_type); - printf("pr %d\n",star->tides_viscous_time_scale_prescription); - printf("M %g\n",M); - printf("star->convective_envelope_mass %d\n",star->convective_envelope_mass); - printf("m %g\n",m); - printf("a %g\n",a); - printf("R %g\n",R); - printf("star->convective_envelope_radius %g\n",star->convective_envelope_radius); - printf("star->luminosity %g\n",star->luminosity); - } - - double tau = 3.0*(1.0 + 1.0/(2.0*k_AM))*R*R*R/(CONST_G*M*t_V); - - double I = rg*M*R*R; // moment of intertia - - double R_div_a = R/a; - double R_div_a_p5 = pow(R_div_a,5.0); - double t_f_inv = 3.0*k_AM*tau*n*n*(m/M)*R_div_a_p5; - - double f_tides1 = f_tides1_function_BO(e_p2,j_p10_inv,j_p13_inv); - double f_tides2 = f_tides2_function_BO(e_p2,j_p10_inv,j_p13_inv); - double f_tides3 = f_tides3_function_BO(e_p2,j_p10_inv,j_p13_inv); - double f_tides4 = f_tides4_function_BO(e_p2,j_p10_inv,j_p13_inv); - double f_tides5 = f_tides5_function_BO(e_p2,j_p10_inv,j_p13_inv); - - double spin_vec_dot_e_vec = dot3(spin_vec,e_vec); - double spin_vec_dot_h_vec = dot3(spin_vec,h_vec); - - double q_vec_unit[3]; - cross3(h_vec_unit,e_vec_unit,q_vec_unit); - - double spin_vec_dot_e_vec_unit = dot3(spin_vec,e_vec_unit); - double spin_vec_dot_h_vec_unit = dot3(spin_vec,h_vec_unit); - double spin_vec_dot_q_vec_unit = dot3(spin_vec,q_vec_unit); - double mu = m*M/(m+M); - double C = m*k_AM*R_div_a_p5/(mu*n); - - double C_rot; - double X_rot = 0.0; - double Y_rot = 0.0; - double Z_rot = 0.0; - double Z_TB = 0.0; - if (include_rotation_precession_terms == 1) - { - if (tides_method == 1) - { - C_rot = C*j_p4_inv*spin_vec_dot_h_vec_unit; - X_rot = -C_rot*spin_vec_dot_e_vec_unit; - Y_rot = -C_rot*spin_vec_dot_q_vec_unit; - } -// printf("e %g q %g \n",spin_vec_dot_e_vec_unit/norm3(spin_vec),spin_vec_dot_q_vec_unit/norm3(spin_vec)); - - Z_rot = C*c_1div2*j_p4_inv*(2.0*spin_vec_dot_h_vec_unit*spin_vec_dot_h_vec_unit - spin_vec_dot_q_vec_unit*spin_vec_dot_q_vec_unit - spin_vec_dot_e_vec_unit*spin_vec_dot_e_vec_unit); -// printf("1 %g 2 %g 3 %g\n",2.0*spin_vec_dot_h_vec_unit*spin_vec_dot_h_vec_unit ,- spin_vec_dot_q_vec_unit*spin_vec_dot_q_vec_unit ,- spin_vec_dot_e_vec_unit*spin_vec_dot_e_vec_unit); -// printf("X %g Y %g Z %g\n",X_rot,Y_rot,Z_rot); - } - if (include_tidal_bulges_precession_terms == 1) - { - Z_TB = C*15.0*n*n*(mu/M)*f_tides2; - } - - double X = X_rot; - double Y = Y_rot; - double Z = Z_rot + Z_TB; - - //printf("M %g m %g R %g k_AM %g a %g e %g Z %g Z_rot %g Z_TB %g\n",M,R,k_AM,a,e,Z,Z_rot,Z_TB); - - - double dh_vec_dt_star_i; - - for (int i=0; i<3; i++) - { - - if (include_tidal_friction_terms == 1) - { - dh_vec_dt_star_i = -t_f_inv*( (h/(2.0*n))*(spin_vec_dot_e_vec*f_tides5*e_vec[i] - spin_vec[i]*f_tides3) \ - + h_vec[i]*(f_tides4 - spin_vec_dot_h_vec*f_tides2/(2.0*n*h)) ); - binary->dh_vec_dt[i] += dh_vec_dt_star_i; - - binary->de_vec_dt[i] += -(t_f_inv/h)*( spin_vec_dot_e_vec*f_tides2*h_vec[i]/(2.0*n) \ - + 9.0*e_vec[i]*(f_tides1*h - c_11div18*spin_vec_dot_h_vec*f_tides2/n) ); - star->dspin_vec_dt[i] += -dh_vec_dt_star_i/I; - //printf("test %g %g\n",spin_vec_dot_e_vec*f_tides5*e_vec[i] - spin_vec[i]*f_tides3); - } - if (include_rotation_precession_terms == 1 || include_tidal_bulges_precession_terms == 1) - { - if (e >= minimum_eccentricity_for_tidal_precession) - { - binary->de_vec_dt[i] += e*(Z*q_vec_unit[i] - Y*h_vec_unit[i]); - - dh_vec_dt_star_i = h*(-X*q_vec_unit[i] + Y*e_vec_unit[i]); - binary->dh_vec_dt[i] += dh_vec_dt_star_i; - star->dspin_vec_dt[i] += -dh_vec_dt_star_i/I; - -// printf("ok %d %d\n",include_rotation_precession_terms,include_tidal_bulges_precession_terms); - } - } - } - -// printf("I %g %g %g %g\n",rg,M,R,Q_prime); -// printf("f dh_vec_dt %g %g %g\n",binary->dh_vec_dt[0],binary->dh_vec_dt[1],binary->dh_vec_dt[2]); -// printf("f dspin_vec_dt %g %g %g\n",star->dspin_vec_dt[0],star->dspin_vec_dt[1],star->dspin_vec_dt[2]); - return 0; -} - - -double f_tides1_function_BO(double e_p2, double j_p10_inv, double j_p13_inv) -{ - return j_p13_inv*(1.0 + e_p2*(c_15div4 + e_p2*(c_15div8 + e_p2*c_5div64))); -} -double f_tides2_function_BO(double e_p2, double j_p10_inv, double j_p13_inv) -{ - return j_p10_inv*(1.0 + e_p2*(c_3div2 + e_p2*c_1div8)); -} -double f_tides3_function_BO(double e_p2, double j_p10_inv, double j_p13_inv) -{ - return j_p10_inv*(1.0 + e_p2*(c_9div2 + e_p2*c_5div8)); -} -double f_tides4_function_BO(double e_p2, double j_p10_inv, double j_p13_inv) -{ - return j_p13_inv*(1.0 + e_p2*(c_15div2 + e_p2*(c_45div8 + e_p2*c_5div16))); -} -double f_tides5_function_BO(double e_p2, double j_p10_inv, double j_p13_inv) -{ - return j_p10_inv*(3.0 + c_1div2*e_p2); -} - - -double compute_EOM_equilibrium_tide(ParticlesMap *particlesMap, int binary_index, int star_index, int companion_index, int include_tidal_friction_terms, int include_tidal_bulges_precession_terms, int include_rotation_precession_terms, double minimum_eccentricity_for_tidal_precession) - -/* Equilibrium tide in vector form adopted from Eggleton & Kisseleva 1998 */ - -/* NOTE: in SecularMultiple, the h-vector is defined as the orbital angular momentum vector, - * NOT the SPECIFIC orbital angular momentum vector. Compared to the notation used by Eggleton, - * h_vec_SecularMultiple = mu*h_vec_Eggleton where mu = m*M/(m+M) is the reduced mass. - * In particular, note the line `star->dspin_vec_dt[i] += -dh_vec_dt_star[i]/I;' */ - -{ -// printf("tides EK \n"); -// printf("TIDES %d %d %d\n",binary_index,star_index,companion_index); - Particle *binary = (*particlesMap)[binary_index]; - Particle *star = (*particlesMap)[star_index]; - Particle *companion = (*particlesMap)[companion_index]; - - /* orbit quantities */ - double e = binary->e; - double e_p2 = binary->e_p2; - double a = binary->a; - double h = binary->h; - double *e_vec = binary->e_vec; - double *h_vec = binary->h_vec; - double *e_vec_unit = binary->e_vec_unit; - double *h_vec_unit = binary->h_vec_unit; - double j = binary->j; - double j_p2 = binary->j_p2; - double j_p3 = binary->j_p3; - double j_p4 = binary->j_p4; - double j_p8 = j_p4*j_p4; - double j_p10 = j_p2*j_p8; - double j_p13 = j_p3*j_p10; - double j_p4_inv = 1.0/j_p4; - double j_p10_inv = 1.0/j_p10; - double j_p13_inv = 1.0/j_p13; - double P_orb = compute_orbital_period(binary); - double n = 2.0*M_PI/P_orb; /* mean motion */ - - /* stellar properties */ - double *spin_vec = star->spin_vec; - double M = star->mass; - double m = companion->mass; - double mu = m*M/(m+M); - double R = star->radius; - double k_AM = star->tides_apsidal_motion_constant; - double t_V = compute_t_V(star,companion,a); - star->tides_viscous_time_scale = t_V; - double rg = star->tides_gyration_radius; - double I = rg*M*R*R; // moment of intertia - - double R_div_a = R/a; - double R_div_a_p5 = pow(R_div_a,5.0); - double R_div_a_p8 = pow(R_div_a,8.0); - double t_f_inv = (9.0/t_V)*R_div_a_p8*((M+m)*m/(M*M))*(1.0 + 2.0*k_AM)*(1.0 + 2.0*k_AM); - - double q_vec_unit[3]; - cross3(h_vec_unit,e_vec_unit,q_vec_unit); - - double spin_vec_dot_e_vec_unit = dot3(spin_vec,e_vec_unit); - double spin_vec_dot_h_vec_unit = dot3(spin_vec,h_vec_unit); - double spin_vec_dot_q_vec_unit = dot3(spin_vec,q_vec_unit); - - double V,W,X,Y,Z; - VWXYZ_tides_function( - include_tidal_friction_terms, include_tidal_bulges_precession_terms, include_rotation_precession_terms, minimum_eccentricity_for_tidal_precession, \ - t_f_inv,k_AM, \ - m, M, mu, n, R_div_a_p5, \ - e, e_p2, j_p4_inv, j_p10_inv, j_p13_inv, \ - spin_vec_dot_h_vec_unit, spin_vec_dot_e_vec_unit, spin_vec_dot_q_vec_unit, \ - &V, &W, &X, &Y, &Z); - - //printf("t_f_inv V %g W %g X %g Y %g Z %g\n",t_f_inv,V,W,X,Y,Z); - -// printf("js %g %g %g\n",j_p10_inv,j_p13_inv); -// printf("fs %g %g %g %g %g \n",f_tides1,f_tides2,f_tides3,f_tides4,f_tides5); - - double dh_vec_dt_star[3]; - - for (int i=0; i<3; i++) - { - dh_vec_dt_star[i] = h*( Y*e_vec_unit[i] - W*h_vec_unit[i] - X*q_vec_unit[i] ); - binary->dh_vec_dt[i] += dh_vec_dt_star[i]; - - binary->de_vec_dt[i] += e*( -V*e_vec_unit[i] - Y*h_vec_unit[i] + Z*q_vec_unit[i] ); - - star->dspin_vec_dt[i] += -dh_vec_dt_star[i]/I; /* conservation of total angular momentum (orbit+spin) */ - - - - -// printf("test %g %g\n",I*spin_vec[2], h_vec[2]); -// printf("test2 %g %g %g\n",I*spin_vec[0] + h_vec[0],I*spin_vec[1] + h_vec[1],I*spin_vec[2] + h_vec[2]); -// printf("test2 %g %g %g\n",I*spin_vec[0] + mu*h_vec[0],I*spin_vec[1] + mu*h_vec[1],I*spin_vec[2] + mu*h_vec[2]); - } - -// double omega = norm3(spin_vec); -// double h2 = sqrt(CONST_G*(M+m)*a*(1.0-e*e)); - -// printf("R %g\n",h/(mu*h2)); -// printf("H%g H_a %g H_b %g\n",mu*h2 + I*omega, mu*h2, I*omega); -// printf("H%g H_a %g H_b %g\n",mu*h + I*omega, mu*h, I*omega); - -// printf("I %g %g %g %g\n",rg,M,R,Q_prime); -// printf("f dh_vec_dt %g %g %g\n",binary->dh_vec_dt[0],binary->dh_vec_dt[1],binary->dh_vec_dt[2]); -// printf("f dspin_vec_dt %g %g %g\n",star->dspin_vec_dt[0],star->dspin_vec_dt[1],star->dspin_vec_dt[2]); - return 0; -} - -double f_tides1_function(double e_p2, double j_p10_inv, double j_p13_inv) -{ - return j_p13_inv*(1.0 + e_p2*(c_15div4 + e_p2*(c_15div8 + e_p2*c_5div64))); -} -double f_tides2_function(double e_p2, double j_p10_inv, double j_p13_inv) -{ - return j_p10_inv*(1.0 + e_p2*(c_3div2 + e_p2*c_1div8)); -} -double f_tides3_function(double e_p2, double j_p10_inv, double j_p13_inv) -{ - return j_p13_inv*(1.0 + e_p2*(c_15div2 + e_p2*(c_45div8 + e_p2*c_5div16))); -} -double f_tides4_function(double e_p2, double j_p10_inv, double j_p13_inv) -{ - return j_p10_inv*(1.0 + e_p2*(3.0 + e_p2*c_3div8)); -} -double f_tides5_function(double e_p2, double j_p10_inv, double j_p13_inv) -{ - return j_p10_inv*(1.0 + e_p2*(c_9div2 + e_p2*c_5div8)); -} - - -int VWXYZ_tides_function -( - int include_tidal_friction_terms, int include_tidal_bulges_precession_terms, int include_rotation_precession_terms, double minimum_eccentricity_for_tidal_precession, \ - double t_f_inv, double k_AM, \ - double m, double M, double mu, double n, double R_div_a_p5, \ - double e, double e_p2, double j_p4_inv, double j_p10_inv,double j_p13_inv, \ - double spin_vec_dot_h_vec_unit, double spin_vec_dot_e_vec_unit,double spin_vec_dot_q_vec_unit, \ - double* V, double* W, double* X, double* Y, double* Z -) -{ - - *V = 0.0; - *W = 0.0; - *X = 0.0; - *Y = 0.0; - *Z = 0.0; - - double f2 = f_tides2_function(e_p2,j_p10_inv,j_p13_inv); /* needed for both pure tidal dissipation and pure tidal bulges terms */ - -// if (e < minimum_eccentricity_for_tidal_precession) -// { -// return 0; -// } - - - if (include_tidal_friction_terms == 1) - { - double f1 = f_tides1_function(e_p2,j_p10_inv,j_p13_inv); - double f3 = f_tides3_function(e_p2,j_p10_inv,j_p13_inv); - double f4 = f_tides4_function(e_p2,j_p10_inv,j_p13_inv); - double f5 = f_tides5_function(e_p2,j_p10_inv,j_p13_inv); - - *V += 9.0*t_f_inv*(f1 - c_11div18*(spin_vec_dot_h_vec_unit/n)*f2); - *W += t_f_inv*(f3 - (spin_vec_dot_h_vec_unit/n)*f4); - *X += -t_f_inv*spin_vec_dot_q_vec_unit*f5/(2.0*n); - *Y += t_f_inv*spin_vec_dot_e_vec_unit*f2/(2.0*n); -// printf("TF X %g Y %g V %g W %g\n",*X,*Y,*Z,*V,*W); - - } - - if (e < minimum_eccentricity_for_tidal_precession) - { - return 0; - } - - - if ((include_tidal_bulges_precession_terms == 1) || (include_rotation_precession_terms) == 1) - { - double C = m*k_AM*R_div_a_p5/(mu*n); - - if (include_tidal_bulges_precession_terms == 1) - { - *Z += C*15.0*n*n*(mu/M)*f2; -// printf("include_tidal_bulges_precession_terms Z %g\n",*Z); - } - if (include_rotation_precession_terms == 1) - { - double C_XY = -C*spin_vec_dot_h_vec_unit*j_p4_inv; - *X += C_XY*spin_vec_dot_e_vec_unit; - *Y += C_XY*spin_vec_dot_q_vec_unit; - - -// printf("ROT X %g Y %g Z %g\n",C_XY*spin_vec_dot_e_vec_unit,C_XY*spin_vec_dot_q_vec_unit,C*c_1div2*j_p4_inv*(2.0*spin_vec_dot_h_vec_unit*spin_vec_dot_h_vec_unit - spin_vec_dot_q_vec_unit*spin_vec_dot_q_vec_unit - spin_vec_dot_e_vec_unit*spin_vec_dot_e_vec_unit)); -// -// printf("Z1 %g\n",*Z); - *Z += C*c_1div2*j_p4_inv*(2.0*spin_vec_dot_h_vec_unit*spin_vec_dot_h_vec_unit - spin_vec_dot_q_vec_unit*spin_vec_dot_q_vec_unit - spin_vec_dot_e_vec_unit*spin_vec_dot_e_vec_unit); -// printf("Z2 %g\n",*Z); -// printf("O %g %g %g\n",spin_vec_dot_h_vec_unit,spin_vec_dot_e_vec_unit,spin_vec_dot_q_vec_unit); -// printf("include_rotation_precession_terms Z %g\n",*Z); - } - } - return 0; -} - diff --git a/src/amuse/community/secularmultiple/src/tides.h b/src/amuse/community/secularmultiple/src/tides.h deleted file mode 100644 index e72fc1bedc..0000000000 --- a/src/amuse/community/secularmultiple/src/tides.h +++ /dev/null @@ -1,46 +0,0 @@ -#include "types.h" - -bool check_for_radiative_damping(int stellar_type, double mass, double convective_envelope_mass, double convective_envelope_radius); -bool check_for_convective_damping(int stellar_type); - -double from_k_AM_div_T_to_t_V(double k_AM_div_T, double apsidal_motion_constant); - -double compute_t_V(Particle *star, Particle *companion, double semimajor_axis); -double compute_t_V_hurley -( - int stellar_type, - double mass, - double convective_envelope_mass, - double companion_mass, - double semimajor_axis, - double radius, - double convective_envelope_radius, - double luminosity, - double spin_angular_frequency, - double gyration_radius, - double apsidal_motion_constant -); - -double compute_EOM_equilibrium_tide(ParticlesMap *particlesMap, int binary_index, int star_index, int companion_index, int include_tidal_friction_terms, int include_tidal_bulges_precession_terms, int include_rotation_precession_terms, double minimum_eccentricity_for_tidal_precession); -double f_tides1_function(double e_p2, double j_p10_inv, double j_p13_inv); -double f_tides2_function(double e_p2, double j_p10_inv, double j_p13_inv); -double f_tides3_function(double e_p2, double j_p10_inv, double j_p13_inv); -double f_tides4_function(double e_p2, double j_p10_inv, double j_p13_inv); -double f_tides5_function(double e_p2, double j_p10_inv, double j_p13_inv); - -double compute_EOM_equilibrium_tide_BO_full(ParticlesMap *particlesMap, int binary_index, int star_index, int companion_index, int include_tidal_friction_terms, int include_tidal_bulges_precession_terms, int include_rotation_precession_terms, double minimum_eccentricity_for_tidal_precession, int tides_method); -double f_tides1_function_BO(double e_p2, double j_p10_inv, double j_p13_inv); -double f_tides2_function_BO(double e_p2, double j_p10_inv, double j_p13_inv); -double f_tides3_function_BO(double e_p2, double j_p10_inv, double j_p13_inv); -double f_tides4_function_BO(double e_p2, double j_p10_inv, double j_p13_inv); -double f_tides5_function_BO(double e_p2, double j_p10_inv, double j_p13_inv); - -int VWXYZ_tides_function -( - int include_tidal_friction_terms, int include_tidal_bulges_precession_terms, int include_rotation_precession_terms, double minimum_eccentricity_for_tidal_precession, \ - double t_f_inv, double k_AM, \ - double m, double M, double mu, double n, double R_div_a_p5, \ - double e, double e_p2, double j_p4_inv, double j_p10_inv,double j_p13_inv, \ - double spin_vec_dot_h_vec_unit, double spin_vec_dot_e_vec_unit,double spin_vec_dot_q_vec_unit, \ - double* V, double* W, double* X, double* Y, double* Z -); diff --git a/src/amuse/community/secularmultiple/src/types.cpp b/src/amuse/community/secularmultiple/src/types.cpp deleted file mode 100644 index 9f379a14ff..0000000000 --- a/src/amuse/community/secularmultiple/src/types.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "types.h" - -void Particle::set_ODE_quantities(double delta_time) -{ - for (int i=0; i<3; i++) - { - dspin_vec_dt[i] = 0.0; - de_vec_dt[i] = 0.0; - dh_vec_dt[i] = 0.0; - } - - e = norm3(e_vec); - h = norm3(h_vec); - spin_vec_norm = norm3(spin_vec); - - for (int i=0; i<3; i++) - { - e_vec_unit[i] = e_vec[i]/e; - h_vec_unit[i] = h_vec[i]/h; - } - - e_p2 = e*e; - j_p2 = 1.0 - e_p2; - j = sqrt(j_p2); - j_p3 = j*j_p2; - j_p4 = j*j_p3; - j_p5 = j*j_p4; - - - a = h*h*child1_mass_plus_child2_mass/( CONST_G*child1_mass_times_child2_mass*child1_mass_times_child2_mass*j_p2 ); - - /* assuming constant semimajor axis with mass loss */ - //double factor_h_vec = (child1_mass_dot_external/(2.0*child1_mass))*(1.0 + child2_mass/child1_mass_plus_child2_mass) + (child2_mass_dot_external/(2.0*child2_mass))*(1.0 + child1_mass/child1_mass_plus_child2_mass); - /* assuming constant SPECIFIC orbital angular momentum with mass loss, i.e. a(m1+m2)=const. */ - double factor_h_vec = child1_mass_dot_external/child1_mass + child2_mass_dot_external/child2_mass - (child1_mass_dot_external + child2_mass_dot_external)/child1_mass_plus_child2_mass; - - /* assuming constant spin angular momentum of the body */ - double factor_spin_vec = - (mass_dot_external/mass + 2.0*radius_dot_external/radius); - - /* set external time derivatives if appropriate */ - double h_vec_dot_external[3] = {h_vec_x_dot_external,h_vec_y_dot_external,h_vec_z_dot_external}; - double e_vec_dot_external[3] = {e_vec_x_dot_external,e_vec_y_dot_external,e_vec_z_dot_external}; - double spin_vec_dot_external[3] = {spin_vec_x_dot_external,spin_vec_y_dot_external,spin_vec_z_dot_external}; - - for (int i=0; i<3; i++) - { - dspin_vec_dt[i] = spin_vec[i]*factor_spin_vec + spin_vec_dot_external[i]; - de_vec_dt[i] = e_vec_dot_external[i]; - dh_vec_dt[i] = h_vec[i]*factor_h_vec + h_vec_dot_external[i]; - } - dmass_dt = mass_dot_external; - dradius_dt = radius_dot_external + radius_ddot_external*delta_time; - -} - -void Particle::reset_ODE_quantities() -{ - for (int i=0; i<3; i++) - { - dspin_vec_dt[i] = 0.0; - de_vec_dt[i] = 0.0; - dh_vec_dt[i] = 0.0; - } -} diff --git a/src/amuse/community/secularmultiple/src/types.h b/src/amuse/community/secularmultiple/src/types.h deleted file mode 100644 index 1a48de130e..0000000000 --- a/src/amuse/community/secularmultiple/src/types.h +++ /dev/null @@ -1,520 +0,0 @@ -#include -#include -#include -#include - -/* constants */ -/* units (cf. interface.py): - * unit_l = units.AU - * unit_m = units.MSun - * unit_t = 1.0e6*units.yr - */ - -#ifndef __FOUND_ROOT -#define ___FOUND_ROOT -#define FOUND_ROOT ((roots_found[i_root] == 1) || (roots_found[i_root] == -1)) -#endif - -#ifndef __CONSTANTS -#define __CONSTANTS -#define CONST_G (double) 3.94852492465e+13 -#define CONST_G_P2 (double) CONST_G*CONST_G -#define CONST_G_P3 (double) CONST_G*CONST_G_P2 -#define CONST_C_LIGHT (double) 63239726386.8 -#define CONST_C_LIGHT_P2 (double) CONST_C_LIGHT*CONST_C_LIGHT -#define CONST_C_LIGHT_P4 (double) CONST_C_LIGHT_P2*CONST_C_LIGHT_P2 -#define CONST_C_LIGHT_P5 (double) CONST_C_LIGHT_P4*CONST_C_LIGHT -#define CONST_MSUN (double) 1.0 -#define CONST_R_SUN (double) 0.00464913034382 -#define CONST_L_SUN (double) 2.71040410975e+14 - -#define c_1div2 (double) 1.0/2.0 -#define c_1div3 (double) 1.0/3.0 -#define c_1div4 (double) 1.0/4.0 -#define c_1div5 (double) 1.0/5.0 -#define c_1div6 (double) 1.0/6.0 -#define c_1div7 (double) 1.0/7.0 -#define c_1div8 (double) 1.0/8.0 -#define c_1div10 (double) 1.0/10.0 -#define c_1div15 (double) 1.0/15.0 -#define c_1div16 (double) 1.0/16.0 -#define c_1div30 (double) 1.0/30.0 -#define c_2div3 (double) 2.0/3.0 -#define c_3div2 (double) 3.0/2.0 -#define c_3div4 (double) 3.0/4.0 -#define c_3div5 (double) 3.0/5.0 -#define c_3div8 (double) 3.0/8.0 -#define c_3div32 (double) 3.0/32.0 -#define c_3div1024 (double) 3.0/1024.0 -#define c_4div15 (double) 4.0/15.0 -#define c_5div2 (double) 5.0/2.0 -#define c_5div8 (double) 5.0/8.0 -#define c_5div16 (double) 5.0/16.0 -#define c_5div64 (double) 5.0/64.0 -#define c_7div8 (double) 7.0/8.0 -#define c_8div5 (double) 8.0/5.0 -#define c_8div7 (double) 8.0/7.0 -#define c_9div2 (double) 9.0/2.0 -#define c_9div16 (double) 9.0/16.0 -#define c_9div32 (double) 9.0/32.0 -#define c_11div18 (double) 11.0/18.0 -#define c_15div2 (double) 15.0/2.0 -#define c_15div4 (double) 15.0/4.0 -#define c_15div8 (double) 15.0/8.0 -#define c_15div16 (double) 15.0/16.0 -#define c_16div5 (double) 16.0/5.0 -#define c_25div16 (double) 25.0/16.0 -#define c_25div64 (double) 25.0/64.0 -#define c_31div2 (double) 31.0/2.0 -#define c_32div5 (double) 32.0/5.0 -#define c_37div96 (double) 37.0/96.0 -#define c_45div8 (double) 45.0/8.0 -#define c_64div5 (double) 64.0/5.0 -#define c_73div24 (double) 73.0/24.0 -#define c_105div4096 (double) 105.0/4096.0 -#define c_121div304 (double) 121.0/304.0 -#define c_185div16 (double) 185.0/16.0 -#define c_255div8 (double) 255.0/8.0 -#define c_304div15 (double) 304.0/15.0 -#endif - - -#ifndef __TABLES -#define __TABLES -#define MAX_ORDER (int) 5 - -#define TABLEWIDTH_A (int) 3 -#define TABLELENGTH_A (int) 10 -const double A_TABLE[TABLELENGTH_A][TABLEWIDTH_A] = -{{2, 0, -0.500000000000000}, {2, 2, 1.50000000000000}, {3, - 1, -1.50000000000000}, {3, 3, 2.50000000000000}, {4, 0, - 0.375000000000000}, {4, 2, -3.75000000000000}, {4, 4, - 4.37500000000000}, {5, 1, 1.87500000000000}, {5, - 3, -8.75000000000000}, {5, 5, 7.87500000000000}}; - -#define TABLEWIDTH_B (int) 8 -#define TABLELENGTH_B (int) 47 -#define HIGHEST_POWER_ECCP2_IN_B_TABLE (int) 3 -const double B_TABLE[TABLELENGTH_B][TABLEWIDTH_B] = -{{2, 0, 0, 0, 1.00000000000000, 1.50000000000000, 0, 0}, {2, 1, 1, - 0, -2.00000000000000, -0.500000000000000, 0, 0}, {2, 2, 0, 0, - 0.500000000000000, -0.500000000000000, 0, 0}, {2, 2, 0, - 2, -0.500000000000000, 0, 0, 0}, {2, 2, 2, 0, 2.50000000000000, 0, - 0, 0}, {3, 0, 0, 0, 1.00000000000000, 3.00000000000000, - 0.375000000000000, 0}, {3, 1, 1, - 0, -2.50000000000000, -1.87500000000000, 0, 0}, {3, 2, 0, 0, - 0.500000000000000, -0.375000000000000, -0.125000000000000, 0}, {3, - 2, 0, 2, -0.500000000000000, -0.125000000000000, 0, 0}, {3, 2, 2, 0, - 3.75000000000000, 0.625000000000000, 0, 0}, {3, 3, 1, - 0, -1.87500000000000, 1.87500000000000, 0, 0}, {3, 3, 1, 2, - 1.87500000000000, 0, 0, 0}, {3, 3, 3, 0, -4.37500000000000, 0, 0, - 0}, {4, 0, 0, 0, 1.00000000000000, 5.00000000000000, - 1.87500000000000, 0}, {4, 1, 1, - 0, -3.00000000000000, -4.50000000000000, -0.375000000000000, 0}, {4, - 2, 0, 0, 0.500000000000000, -0.125000000000000, -0.375000000000000, - 0}, {4, 2, 0, 2, -0.500000000000000, -0.375000000000000, 0, 0}, {4, - 2, 2, 0, 5.25000000000000, 2.62500000000000, 0, 0}, {4, 3, 1, - 0, -2.25000000000000, 1.87500000000000, 0.375000000000000, 0}, {4, - 3, 1, 2, 2.25000000000000, 0.375000000000000, 0, 0}, {4, 3, 3, - 0, -7.00000000000000, -0.875000000000000, 0, 0}, {4, 4, 0, 0, - 0.375000000000000, -0.750000000000000, 0.375000000000000, 0}, {4, 4, - 0, 2, -0.750000000000000, 0.750000000000000, 0, 0}, {4, 4, 0, 4, - 0.375000000000000, 0, 0, 0}, {4, 4, 2, 0, - 5.25000000000000, -5.25000000000000, 0, 0}, {4, 4, 2, - 2, -5.25000000000000, 0, 0, 0}, {4, 4, 4, 0, 7.87500000000000, 0, 0, - 0}, {5, 0, 0, 0, 1.00000000000000, 7.50000000000000, - 5.62500000000000, 0.312500000000000}, {5, 1, 1, - 0, -3.50000000000000, -8.75000000000000, -2.18750000000000, 0}, {5, - 2, 0, 0, 0.500000000000000, - 0.250000000000000, -0.687500000000000, -0.0625000000000000}, {5, 2, - 0, 2, -0.500000000000000, -0.750000000000000, -0.0625000000000000, - 0}, {5, 2, 2, 0, 7.00000000000000, 7.00000000000000, - 0.437500000000000, 0}, {5, 3, 1, 0, -2.62500000000000, - 1.31250000000000, 1.31250000000000, 0}, {5, 3, 1, 2, - 2.62500000000000, 1.31250000000000, 0, 0}, {5, 3, 3, - 0, -10.5000000000000, -3.93750000000000, 0, 0}, {5, 4, 0, 0, - 0.375000000000000, -0.687500000000000, 0.250000000000000, - 0.0625000000000000}, {5, 4, 0, 2, -0.750000000000000, - 0.625000000000000, 0.125000000000000, 0}, {5, 4, 0, 4, - 0.375000000000000, 0.0625000000000000, 0, 0}, {5, 4, 2, 0, - 7.00000000000000, -6.12500000000000, -0.875000000000000, 0}, {5, 4, - 2, 2, -7.00000000000000, -0.875000000000000, 0, 0}, {5, 4, 4, 0, - 13.1250000000000, 1.31250000000000, 0, 0}, {5, 5, 1, - 0, -2.18750000000000, 4.37500000000000, -2.18750000000000, 0}, {5, - 5, 1, 2, 4.37500000000000, -4.37500000000000, 0, 0}, {5, 5, 1, - 4, -2.18750000000000, 0, 0, 0}, {5, 5, 3, 0, -13.1250000000000, - 13.1250000000000, 0, 0}, {5, 5, 3, 2, 13.1250000000000, 0, 0, - 0}, {5, 5, 5, 0, -14.4375000000000, 0, 0, 0}}; - -#define TABLEWIDTH_D (int) 8 -#define TABLELENGTH_D (int) 15 -const double D_TABLE[TABLELENGTH_D][TABLEWIDTH_D] = -{ - {2, 0, 0, 0, 0, 0, 0, 1}, \ - {2, 0, 2, 0, 0, 0, 0, 2}, \ - {2, 0, 2, 0, 2, 0, 0, 3}, \ - {2, 0, 2, 0, 0, 0, 2, 4}, \ - {2, 2, 0, 0, 0, 0, 0, 5}, \ - {2, 2, 0, 2, 0, 0, 0, 6}, \ - {2, 2, 0, 0, 0, 2, 0, 7}, \ - {3, 1, 0, 1, 0, 0, 0, 8}, \ - {3, 1, 2, 0, 1, 1, 1, 9}, \ - {3, 1, 2, 1, 0, 0, 0, 10}, \ - {3, 1, 2, 1, 0, 0, 2, 11}, \ - {3, 1, 2, 1, 2, 0, 0, 12}, \ - {3, 3, 0, 1, 0, 0, 0, 13}, \ - {3, 3, 0, 1, 0, 2, 0, 14}, \ - {3, 3, 0, 3, 0, 0, 0, 15} -}; - -/* the numbers in each last entry of the D table refer to the functions defined below */ - -inline double D_TABLE_FUNC1(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 2.0*(sqrt_ef_p2_minus_one + asec_minus_ef); -} -inline double D_TABLE_FUNC1_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 0.0; -} - -inline double D_TABLE_FUNC2(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return (1.0 - ep_p2)*( c_1div3*one_div_ef_p2*sqrt_ef_p2_minus_one*(1.0 + 2.0*ef_p2) + asec_minus_ef); -} -inline double D_TABLE_FUNC2_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return -2.0*ep*( c_1div3*one_div_ef_p2*sqrt_ef_p2_minus_one*(1.0 + 2.0*ef_p2) + asec_minus_ef); -} - -inline double D_TABLE_FUNC3(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return -c_1div3*one_div_ef_p2*sqrt_ef_p2_minus_one*(1.0 + 2.0*ef_p2) - asec_minus_ef; -} -inline double D_TABLE_FUNC3_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 0.0; -} - -inline double D_TABLE_FUNC4(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return c_2div3*one_div_ef_p2*ef_p2_minus_one*sqrt_ef_p2_minus_one; -} -inline double D_TABLE_FUNC4_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 0.0; -} - -inline double D_TABLE_FUNC5(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return ep_p2*( c_1div3*one_div_ef_p2*sqrt_ef_p2_minus_one*(1.0 + 2.0*ef_p2) + asec_minus_ef); -} -inline double D_TABLE_FUNC5_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 2.0*ep*( c_1div3*one_div_ef_p2*sqrt_ef_p2_minus_one*(1.0 + 2.0*ef_p2) + asec_minus_ef); -} - -inline double D_TABLE_FUNC6(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return c_2div3*one_div_ef_p2*ef_p2_minus_one*sqrt_ef_p2_minus_one; -} -inline double D_TABLE_FUNC6_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 0.0; -} - -inline double D_TABLE_FUNC7(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return -c_1div3*one_div_ef_p2*sqrt_ef_p2_minus_one*(1.0 + 2.0*ef_p2) - asec_minus_ef; -} -inline double D_TABLE_FUNC7_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 0.0; -} -inline double D_TABLE_FUNC8(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 2.0*(c_1div3*one_div_ef_p1*sqrt_ef_p2_minus_one*(1.0 + 2.0*ef_p2) + ef*asec_minus_ef); -} -inline double D_TABLE_FUNC8_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 0.0; -} -inline double D_TABLE_FUNC9(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return c_1div15*one_div_ef_p3*sqrt_ef_p2_minus_one*(2.0 - 9.0*ef_p2 - 8.0*ef_p4) - ef*asec_minus_ef; -} -inline double D_TABLE_FUNC9_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 0.0; -} -inline double D_TABLE_FUNC10(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return (1.0 - ep_p2)*( c_1div30*one_div_ef_p3*sqrt_ef_p2_minus_one*(-2.0 + 9.0*ef_p2 + 8.0*ef_p4) + c_1div2*ef*asec_minus_ef); -} -inline double D_TABLE_FUNC10_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return -2.0*ep*( c_1div30*one_div_ef_p3*sqrt_ef_p2_minus_one*(-2.0 + 9.0*ef_p2 + 8.0*ef_p4) + c_1div2*ef*asec_minus_ef); -} -inline double D_TABLE_FUNC11(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return c_4div15*one_div_ef_p3*ef_p2_minus_one*ef_p2_minus_one*sqrt_ef_p2_minus_one; -} -inline double D_TABLE_FUNC11_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 0.0; -} -inline double D_TABLE_FUNC12(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return c_1div30*one_div_ef_p3*sqrt_ef_p2_minus_one*(2.0 - 9.0*ef_p2 - 8.0*ef_p4) - c_1div2*ef*asec_minus_ef; -} -inline double D_TABLE_FUNC12_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 0.0; -} -inline double D_TABLE_FUNC13(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return ep_p2*( c_1div10*one_div_ef_p3*sqrt_ef_p2_minus_one*(-2.0 + 9.0*ef_p2 + 8.0*ef_p4) + c_3div2*ef*asec_minus_ef ); -} -inline double D_TABLE_FUNC13_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 2.0*ep*( c_1div10*one_div_ef_p3*sqrt_ef_p2_minus_one*(-2.0 + 9.0*ef_p2 + 8.0*ef_p4) + c_3div2*ef*asec_minus_ef ); -} -inline double D_TABLE_FUNC14(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return c_1div10*one_div_ef_p3*sqrt_ef_p2_minus_one*(2.0 - 9.0*ef_p2 - 8.0*ef_p4) - c_3div2*ef*asec_minus_ef; -} -inline double D_TABLE_FUNC14_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 0.0; -} -inline double D_TABLE_FUNC15(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return c_4div15*one_div_ef_p3*ef_p2_minus_one*ef_p2_minus_one*sqrt_ef_p2_minus_one; -} -inline double D_TABLE_FUNC15_DER(double ep, double ep_p2, double ef, double ef_p2, double ef_p4, double one_div_ef_p1, double one_div_ef_p2, double one_div_ef_p3, double ef_p2_minus_one, double sqrt_ef_p2_minus_one, double asec_minus_ef) -{ - return 0.0; -} - - - -#endif - -/* ODE solver macros */ -#ifndef __ODE_MACROS -#define __ODE_MACROS - #define Ith(v,i) NV_Ith_S(v,i-1) /* Ith numbers components 1..NEQ */ - #define IJth(A,i,j) DENSE_ELEM(A,i-1,j-1) /* IJth numbers rows,cols 1..NEQ */ - #ifndef max - #define max( a, b ) ( ((a) > (b)) ? (a) : (b) ) - #endif - #ifndef min - #define min(X,Y) ((X) < (Y) ? (X) : (Y)) - #endif -#endif - -/* vector operators */ -#ifndef __VECTOR_OPERATORS -#define __VECTOR_OPERATORS -inline void cross3(double a[3], double b[3], double result[3]) -{ - result[0] = a[1]*b[2] - a[2]*b[1]; - result[1] = a[2]*b[0] - a[0]*b[2]; - result[2] = a[0]*b[1] - a[1]*b[0]; -} -inline double norm3(double v[3]) -{ - double result = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); - return result; -} -inline double norm3_squared(double v[3]) -{ - double result = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - return result; -} -inline double dot3(double a[3], double b[3]) -{ - double result = (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]); - return result; -} -#endif - -/* classes */ -#ifndef __Particle -#define __Particle -class Particle -{ - public: - /* generic properties */ - int index,child1,child2; - int parent; - int sibling; - std::vector parents; - std::vector connecting_child_in_parents; - int level,highest_level; - int is_binary; - double mass,mass_dot_external,child1_mass,child2_mass,total_system_mass; - - /******************* - /* body properties * - * ****************/ - /* general */ - double radius,radius_dot_external,radius_ddot_external; - double spin_vec_x,spin_vec_y,spin_vec_z; - double spin_vec_x_dot_external,spin_vec_y_dot_external,spin_vec_z_dot_external; - int stellar_type; - - double position_x,position_y,position_z; - double velocity_x,velocity_y,velocity_z; - - /* used in ODE solver only */ - double spin_vec[3],dspin_vec_dt[3]; - double spin_vec_norm; - double dmass_dt,dradius_dt; - - void set_ODE_quantities(double delta_time); - void reset_ODE_quantities(); - - /********************* - /* binary properties * - * ******************/ - /* general */ - double e_vec_x,e_vec_y,e_vec_z; - double h_vec_x,h_vec_y,h_vec_z; - - double e_vec_x_dot_external,e_vec_y_dot_external,e_vec_z_dot_external; - double h_vec_x_dot_external,h_vec_y_dot_external,h_vec_z_dot_external; - - double true_anomaly; - - /* PN terms */ - int include_pairwise_1PN_terms,include_pairwise_25PN_terms; - - /* tidal friction */ - int include_tidal_friction_terms,tides_method,include_tidal_bulges_precession_terms,include_rotation_precession_terms; - double minimum_eccentricity_for_tidal_precession; - double tides_Q_prime; /* depricated */ - double tides_apsidal_motion_constant, tides_time_lag, tides_gyration_radius; - double tides_viscous_time_scale; - int tides_viscous_time_scale_prescription; - double convective_envelope_mass,convective_envelope_radius,luminosity; - - /* root finding */ - int check_for_secular_breakdown,secular_breakdown_has_occurred; - int check_for_dynamical_instability,dynamical_instability_has_occurred,dynamical_instability_criterion; - int dynamical_instability_central_particle; - double dynamical_instability_K_parameter; - int check_for_physical_collision_or_orbit_crossing,physical_collision_or_orbit_crossing_has_occurred; - int check_for_minimum_periapse_distance,minimum_periapse_distance_has_occurred; - double check_for_minimum_periapse_distance_value; - int check_for_RLOF_at_pericentre,check_for_RLOF_at_pericentre_use_sepinsky_fit,RLOF_at_pericentre_has_occurred; - - /* used in ODE solver only */ - double e_vec[3],h_vec[3]; - double e_vec_unit[3],h_vec_unit[3]; - double de_vec_dt[3],dh_vec_dt[3]; - double child1_mass_plus_child2_mass,child1_mass_minus_child2_mass,child1_mass_times_child2_mass; - double child1_mass_dot_external,child2_mass_dot_external; - double e,e_p2; - double j,j_p2,j_p3,j_p4,j_p5; // j=sqrt(1-e^2) - double h,a; - -// Particle(int index, int is_binary, int child1, int child2, double mass, double radius, double spin_vec_x, double spin_vec_y, double spin_vec_z, double e_vec_x, double e_vec_y, double e_vec_z, double h_vec_x, double h_vec_y, double h_vec_z, int include_pairwise_1PN_terms, int include_pairwise_25PN_terms, int include_tides_terms, double tides_Q_prime, double tides_gyration_radius, int check_for_secular_breakdown, int secular_breakdown_has_occurred, int check_for_dynamical_instability, int dynamical_instability_has_occurred, int dynamical_instability_criterion, int check_for_physical_collision, int physical_collision_has_occurred) : index(index), is_binary(is_binary), child1(child1), child2(child2), mass(mass), radius(radius), spin_vec_x(spin_vec_x), spin_vec_y(spin_vec_y), spin_vec_z(spin_vec_z), e_vec_x(e_vec_x), e_vec_y(e_vec_y), e_vec_z(e_vec_z), h_vec_x(h_vec_x), h_vec_y(h_vec_y), h_vec_z(h_vec_z), include_pairwise_1PN_terms(include_pairwise_1PN_terms), include_pairwise_25PN_terms(include_pairwise_25PN_terms), include_tides_terms(include_tides_terms), tides_Q_prime(tides_Q_prime), tides_gyration_radius(tides_gyration_radius), - - /* user-specified instantaneous perturbations */ - int sample_orbital_phases_randomly; - double instantaneous_perturbation_delta_mass; - double instantaneous_perturbation_delta_position_x,instantaneous_perturbation_delta_position_y,instantaneous_perturbation_delta_position_z; - double instantaneous_perturbation_delta_velocity_x,instantaneous_perturbation_delta_velocity_y,instantaneous_perturbation_delta_velocity_z; - - Particle(int index, int is_binary) : index(index), is_binary(is_binary) - { - /* default values */ - check_for_secular_breakdown = 0; - check_for_dynamical_instability = 0; - check_for_physical_collision_or_orbit_crossing = 0; - check_for_minimum_periapse_distance = 0; - check_for_RLOF_at_pericentre = 0; - - secular_breakdown_has_occurred = 0; - dynamical_instability_has_occurred = 0; - physical_collision_or_orbit_crossing_has_occurred = 0; - minimum_periapse_distance_has_occurred = 0; - RLOF_at_pericentre_has_occurred = 0; - - - include_pairwise_1PN_terms = 0; - include_pairwise_25PN_terms = 0; - include_tidal_friction_terms = 0; - include_tidal_bulges_precession_terms = 0; - include_rotation_precession_terms = 0; - - radius = 1.0e-15; /* this must be set (to nonzero), otherwise ODE solver will have invalid ewt values */ - tides_viscous_time_scale_prescription = 0; /* constant, user-specified t_V */ - minimum_eccentricity_for_tidal_precession = 1.0e-3; - spin_vec_x_dot_external = spin_vec_y_dot_external = spin_vec_z_dot_external = 0.0; - mass_dot_external = radius_dot_external = radius_ddot_external = 0.0; - - sample_orbital_phases_randomly = 1; - instantaneous_perturbation_delta_mass = 0.0; - instantaneous_perturbation_delta_position_x = instantaneous_perturbation_delta_position_y = instantaneous_perturbation_delta_position_z = 0.0; - instantaneous_perturbation_delta_velocity_x = instantaneous_perturbation_delta_velocity_y = instantaneous_perturbation_delta_velocity_z = 0.0; - - } -}; -#endif - -typedef std::map ParticlesMap; -typedef std::map::iterator ParticlesMapIterator; - - - - -#ifndef __External_Particle -#define __External_Particle -class External_Particle -{ - public: - /* generic properties */ - int index; - int mode; - int path; - double mass; - double t_ref,t_passed; - double eccentricity,periapse_distance; - - double r_vec_x,r_vec_y,r_vec_z; - - /* straight line */ - double r0_vec_x,r0_vec_y,r0_vec_z; - double rdot_vec_x,rdot_vec_y,rdot_vec_z; - - /* hyperbolic orbit */ - double e_hat_vec_x,e_hat_vec_y,e_hat_vec_z; - double h_hat_vec_x,h_hat_vec_y,h_hat_vec_z; - - External_Particle(int index) : index(index) - { - mode = 0; - path = 0; - } - -}; -#endif - -typedef std::map External_ParticlesMap; -typedef std::map::iterator External_ParticlesMapIterator; - - - -/* CVODE UserData */ -#ifndef __UserData -#define __UserData -typedef struct { - ParticlesMap *particlesMap; - External_ParticlesMap *external_particlesMap; - double hamiltonian; - int N_root_finding; - double start_time; -} *UserData; -#endif