static void cps_set_frame_rate_or_disable(void* data, const Rational* frameRate) { ClipSource* clipSource = (ClipSource*)data; msc_set_frame_rate_or_disable(clipSource->targetSource, frameRate); clipSource->start = convert_length(clipSource->start, &clipSource->frameRate, frameRate); clipSource->duration = convert_length(clipSource->duration, &clipSource->frameRate, frameRate); clipSource->frameRate = *frameRate; }
static void bks_set_frame_rate_or_disable(void* data, const Rational* frameRate) { BlankSource* source = (BlankSource*)data; if (source->streamInfo.isHardFrameRate && memcmp(frameRate, &source->streamInfo.frameRate, sizeof(*frameRate)) != 0) { msc_disable_stream(&source->mediaSource, 0); return; } source->length = convert_length(source->length, &source->streamInfo.frameRate, frameRate); source->position = convert_length(source->position, &source->streamInfo.frameRate, frameRate); source->streamInfo.frameRate = *frameRate; }
static void mls_set_frame_rate_or_disable(void* data, const Rational* frameRate) { MultipleMediaSources* multSource = (MultipleMediaSources*)data; MediaSourceElement* ele = &multSource->sources; int i; while (ele != NULL && ele->source != NULL) { msc_set_frame_rate_or_disable(ele->source, frameRate); /* recalculate disabledStreamCount */ ele->disabledStreamCount = 0; for (i = 0; i < ele->numStreams; i++) { if (msc_stream_is_disabled(ele->source, i)) { ele->disabledStreamCount++; } } ele = ele->next; } multSource->maxLength = convert_length(multSource->maxLength, &multSource->maxLengthFrameRate, frameRate); multSource->maxLengthFrameRate = *frameRate; }
static void sts_set_frame_rate_or_disable(void* data, const Rational* frameRate) { SystemTimecodeSource* source = (SystemTimecodeSource*)data; if (source->streamInfo.isHardFrameRate && memcmp(frameRate, &source->streamInfo.frameRate, sizeof(*frameRate)) != 0) { msc_disable_stream(&source->mediaSource, 0); return; } source->startTimecode = convert_non_drop_timecode(source->startTimecode, &source->streamInfo.frameRate, frameRate); source->length = convert_length(source->length, &source->streamInfo.frameRate, frameRate); source->position = convert_length(source->position, &source->streamInfo.frameRate, frameRate); source->streamInfo.frameRate = *frameRate; }
void convert_inputs(double in_params[][2], double* out_params) { out_params[0] = convert_mass(in_params[0][0], in_params[0][1]); out_params[1] = convert_length(in_params[1][0], in_params[1][1]); out_params[2] = convert_energy(in_params[2][0], in_params[2][1]); if (DEBUG) { for (int i = 0; i < 3; i++) { printf("%3.8f\r\n", out_params[i]); } } }
int check_fast_approaches( struct particle *parts, struct particle *p, struct particle *pk/*, double r_2*/) { _enter_function(_UL_TIMESTEP, _UL_TIMESTEP_CHECK_FAST_APPROACHES); int i, collision=0; double temp, r_close_2=-1., r_temp_2, t_close, dt=.0, dt2=.0, dt3=.0, dt4=.0, dt5=.0; double *px=p->x, *pv=p->v, *pkx, *pkv, r_2; double x[3], v[3], a[3], a_[3]; assert(p != pk); add_over(1, &count_approach_checks, &count_approach_checks_over); if(pk->active) { pkx = pk->x; pkv = pk->v; } else // have to use predicted x, v and corrected derivatives { #ifndef USE_GRAPE pkx = pk->xp; #else pkx = pk->x; #endif pkv = pk->v; dt = p->t - pk->t; dt2 = .5 * dt * dt; dt3 = dt * dt2 * _1_3; dt4 = .25 * dt * dt3; dt5 = .2 * dt * dt4; } for(i = 0; i < 3; i++) { if( 1 #ifdef USE_GRAPE && pk->active #endif ) { x[i] = px[i] - pkx[i]; } else { x[i] = px[i] - (pkx[i] + dt * pk->v[i] + dt2 * (pk->a[i] + pk->ha[i]) + dt3 * (pk->a_[i] + pk->ha_[i]) + dt4 * (pk->a_2[i] + pk->ha_2[i]) #ifndef USE_GRAPE + dt5 * (pk->a_3[i] + pk->ha_3[i]) #endif ); } if(pk->active) { v[i] = pv[i] - pkv[i]; a[i] = p->ha[i] + p->a[i] - pk->ha[i] - pk->a[i]; a_[i] = p->ha_[i] + p->a_[i] - pk->ha_[i] - pk->a_[i]; } else { v[i] = pv[i] - (pkv[i] + dt * (pk->a[i] + pk->ha[i]) + dt2 * (pk->a_[i] + pk->ha_[i]) + dt3 * (pk->a_2[i] + pk->ha_2[i]) #ifndef USE_GRAPE + dt4 * (pk->a_3[i] + pk->ha_3[i]) #endif ); a[i] = p->ha[i] + p->a[i] - (pk->a[i] + pk->ha[i] + dt * (pk->a_[i] + pk->ha_[i]) + dt2 * (pk->a_2[i] + pk->ha_2[i]) #ifndef USE_GRAPE + dt3 * (pk->a_3[i] + pk->ha_3[i]) #endif ); a_[i] = p->ha_[i] + p->a_[i] - (pk->a_[i] + pk->ha_[i] + dt * (pk->a_2[i] + pk->ha_2[i]) #ifndef USE_GRAPE + dt2* (pk->a_3[i] + pk->ha_3[i]) #endif ); } } r_2 = scal_prod(x, x); // linear approximation of time of closest encounter //t_close = -scal_prod(x, v) / scal_prod(v, v); // 2nd order approximation of time of closest encounter double xv, xa, v2, va, a2, _p, _q, _p3, _q2, _d, _u, _v, dy, t2, t3, _1_a2; xv = scal_prod(x, v); xa = scal_prod(x, a); v2 = scal_prod(v, v); va = scal_prod(v, a); a2 = scal_prod(a, a); _1_a2 = 1. / a2; dy = - va * _1_a2; _p = (a2 * 2.* (v2 + xa) - 3. * va * va) * (_1_a2 * _1_a2); _p3 = _p * _p * _p; _q = (2. * va * va * va - va * 2.*(v2 + xa) * a2 + 2. * xv * a2 * a2) * (_1_a2 * _1_a2 * _1_a2); _q2 = _q * _q; _d = 4. * _p3 + 27. * _q2; if(_d > 0) { _u = -.5 * _q; _v = sqrt(.25 * _q2 + _p3 * _1_27); t_close = cbrt(_u + _v) + cbrt(_u - _v) + dy; } else if(_d == 0) { t_close = cbrt(.5 * _q) + dy; t3 = cbrt(-4. * _q) + dy; if(t3 > 0 && (t3 < t_close || t_close <= 0)) { t_close = t3; } } else // _d < 0 { _u = sqrt(-4. *_1_3 * _p); _v = acos(-.5 * _q * sqrt(-27. / _p3)) * _1_3; t_close = _u * _v + dy; t2 = -_u * (_v + M_PI * _1_3) + dy; t3 = -_u * (_v - M_PI * _1_3) + dy; if(t2 > 0 && (t2 < t_close || t_close <= 0)) t_close = t2; if(t3 > 0 && (t3 < t_close || t_close <= 0)) t_close = t3; } while(1) { // check distance after next step r_temp_2 = .0; for(i = 0; i < DIMENSIONS; i++) { temp = x[i] + p->dt * (v[i] + p->dt * .5 * (a[i] /*+ p->dt / 3. * a_[i]*/)); r_temp_2 += temp * temp; } if(r_2 > r_temp_2 * MAX_APPROACH_FACTOR_2 || r_2 * MAX_APPROACH_FACTOR_2 < r_temp_2) { add_over(1, &count_approach_reduce_t, &count_approach_reduce_t_over); #ifdef DEBUG_ALL fprintf(get_file(FILE_DEBUG), "\t# halving dt: approach m%d - m%d: \tr(t=%1.6e)=%1.2e\t\tr(t=%1.6e)=%1.2e\n", pk->name, p->name, t_total(p->t), convert_length(sqrt(r_2), 0), t_total(p->t+p->dt), convert_length(sqrt(r_temp_2), 0)); fflush(get_file(FILE_DEBUG)); #endif p->dt *= .5; #ifdef SYNCHRONIZE_APPROACHING_TIMESTEPS if(!pk->active) { while(pk->htlast + .5 * pk->dt > p->t + p->dt + DT_TOLERANCE) { pk->dt *= .5; #ifdef DEBUG_ALL fprintf(get_file(FILE_DEBUG), "#### [t=%1.12e] shrinking timestep for m%d as of close encounter with m%d to %e ####\n", t_total(p->t), pk->name, p->name, t_total(pk->dt)); fflush(get_file(FILE_DEBUG)); #endif } } #endif continue; } if(r_2 < 9. * C_2G_C2 * C_2G_C2 * (pk->m + p->m) * (pk->m + p->m)) { // collision in 3 Schwarzschild-radii collision = 1; fprintf(get_file(FILE_WARNING), "#### [t=%1.12e] COLLISION of m%d and m%d at %1.12e: %e (r_S = %e) ####\n", t_total(p->t), p->name, pk->name, t_total(p->t + t_close), convert_length(sqrt(r_2), 0), convert_length(C_2G_C2 * (pk->m + p->m), 0)); fflush(get_file(FILE_WARNING)); } if(t_close > .0 && t_close < p->dt) { // close encounter will happen _during_ next step, now calculate distance if(r_close_2 <.0) { r_close_2 = .0; for(i = 0; i < DIMENSIONS; i++) { temp = (x[i] + t_close * (v[i] + .5 * t_close * a[i])); r_close_2 += temp * temp; } } if(r_close_2 < square(3. * C_2G_C2 * (pk->m + p->m))) { // collision in 3 Schwarzschild-radii collision = 1; fprintf(get_file(FILE_WARNING), "#### [t=%1.12e] COLLISION of m%d and m%d at %1.12e: %e (r_S = %e) ####\n", t_total(p->t), p->name, pk->name, t_total(p->t + t_close), convert_length(sqrt(r_close_2), 0), convert_length(C_2G_C2 * (pk->m + p->m), 0)); fflush(get_file(FILE_WARNING)); } // approach to small multiple of impact parameter: // r'_12 < warn_fact * b = warn_fact * 2 * r_1 * m / M #ifdef WARN_CLOSEENC if(r_close_2 * parts->m * parts->m < square(WARN_APPROACH_FACT * 2 * pk->m) * scal_prod(p->xp, p->xp) && (N_MAX_DETAIL < -1 || p->name <= N_MAX_DETAIL || pk->name <= N_MAX_DETAIL) ) { fprintf(get_file(FILE_WARNING), "\t# predicted close encounter m%d - m%d: \tr(t=%1.6e)=%1.2e\t\tr(t=%1.6e)=%1.2e=%1.2fb\tp.dt=%1.2e\tpk->dt=%1.2e (%1.2e el.) [%d:%d]\n", pk->name, p->name, t_total(p->t), convert_length(sqrt(r_2), 0), t_total(p->t + t_close), convert_length(sqrt(r_close_2), 0), sqrt(r_close_2) / (2. * v_abs(p->xp) * pk->m) * parts->m, convert_time(p->dt, 0), convert_time(pk->dt, 0), convert_time(p->t - pk->t, 0), pk->nearestneighbour, p->nearestneighbour); fprintf(get_file(FILE_WARNING), " PCE %1.12e\t%d\t%e\t%1.10e\t%1.10e\t%1.10e\t%1.10e\t%1.10e\t%1.10e\t%d\t%e\t%1.10e\t%1.10e\t%1.10e\t%1.10e\t%1.10e\t%1.10e\n", t_total(p->t), pk->name, convert_mass(pk->m, 0), convert_length(pkx[0], 0), convert_length(pkx[1], 0), convert_length(pkx[2], 0), convert_length(convert_time(pkv[0], 1), 0), convert_length(convert_time(pkv[1], 1), 0), convert_length(convert_time(pkv[2], 1), 0), p->name, convert_mass(p->m, 0), convert_length(px[0], 0), convert_length(px[1], 0), convert_length(px[2], 0), convert_length(convert_time(pv[0], 1), 0), convert_length(convert_time(pv[1], 1), 0), convert_length(convert_time(pv[2], 1), 0) ); fflush(get_file(FILE_WARNING)); } #endif if(r_2 > MAX_APPROACH_FACTOR_2 * r_close_2) { add_over(1, &count_approach_reduce_t, &count_approach_reduce_t_over); #ifdef DEBUG_ALL fprintf(get_file(FILE_DEBUG), "\t# halving dt: encounter m%d - m%d: \tr(t=%1.6e)=%1.2e\t\tr(t=%1.6e)=%1.2e\tstep: t=%1.6e\n", pk->name, p->name, t_total(p->t), convert_length(sqrt(r_2), 0), t_total(p->t + t_close), convert_length(sqrt(r_close_2), 0), t_total(p->t + p->dt)); fflush(get_file(FILE_DEBUG)); #endif p->dt *= .5; #ifdef SYNCHRONIZE_APPROACHING_TIMESTEPS if(!pk->active) while(pk->htlast + .5 * pk->dt > p->t + p->dt + DT_TOLERANCE) { pk->dt *= .5; #ifdef DEBUG_ALL fprintf(get_file(FILE_DEBUG), "#### shrinking. timestep for m%d as of close encounter with m%d to %e ####\n", t_total(p->t), pk->name, p->name, t_total(pk->dt)); #endif } #endif continue; } } break; } _exit_function(); return collision; }
/* * Calculate Kepler position and velocity for given timestep _dt_ * for particle no. _pos_. * _xp_ and _vp_ will be updated. */ void step_kepler_1(struct particle parts[], int pcount, int pos, double dt, double *out_a, double *out_a_, double *out_a_2, double *out_a_3, double *curr_a, double *curr_e) { _enter_function(_UL_KEPLER, _UL_KEPLER_STEP_KEPLER_1); int i; struct particle *p0 = parts, *p1 = parts + pos; double r_[3], v_[3], j_[3], ecc_[3], a_[3], b_[3], _1_r2, afact, v_r_, v_v_, r_a_, v_a_, r_a__; double ecc, a, r, v, b, omega, e, mean, cosp, sinp; double m_c=p0->m, _cosp_ecc, e2, _1_ecc, _cosp_1, de_dt;//+p1->m; // get relative position / motion for(i = 0; i < 3; i++) { r_[i] = p1->xp[i] - p0->xp[i]; v_[i] = p1->vp[i] - p0->vp[i]; } // calculate ellipse constants get_constants(r_, v_, m_c, j_, ecc_, &a, &omega); //printf("# [%d]:\t%e\t%e\t%e\n", pos, v_abs(ecc_), a, omega); ecc = v_abs(ecc_); // b_ = a * sqrt(|1-e²|) * (j_ x e_) / |j_ x e_| vec_prod(j_, ecc_, b_); b = a * sqrt(fabs(1-ecc*ecc)) / v_abs(b_); for(i = 0; i < 3; i++) { a_[i] = a*ecc_[i]/ecc; // semi major vector b_[i] *= b; // semi minor vector } if(curr_a != NULL) *curr_a = a; if(curr_e != NULL) *curr_e = ecc; if(ecc < 1) // elliptical orbit { if(!p1->is_elliptical) { fprintf(get_file(FILE_WARNING), "#### [t=%1.12e] Particle #%d captured onto elliptical orbit with e=%e ####\n", t_total(p1->t), pos, ecc); p1->is_elliptical = 1; } // calculate eccentric anomaly e at t+dt e = (a - v_abs(r_)) / (ecc * a); if(e >= 1.0) e = .0; else if(e <= -1.0) e = M_PI; else e = acos(e); if(scal_prod(r_, b_) < 0) e = 2*M_PI - e; mean = (e - ecc*sin(e)) + dt * omega; while(mean >= 2. * M_PI) mean -= 2. * M_PI; e = solve_kepler(mean, ecc); cosp = cos(e); sinp = sin(e); _cosp_ecc = cosp - ecc; de_dt = omega / (1. - ecc * cosp); if(ecc > .99) { e2 = (e > 2. * M_PI - 1e-3) ? e - 2. * M_PI : e; if(e2 < 1e-3) { e2 *= e2; _1_ecc = scal_prod(j_, j_)/(p0->m*a*(1+ecc)); _cosp_1 = - .5 * e2 * (1 - e2 / 12. * (1 - e2 / 30.)); _cosp_ecc = _1_ecc + _cosp_1; de_dt = omega / (_1_ecc - ecc * _cosp_1); } } for(i = 0; i < DIMENSIONS; i++) { r_[i] = a_[i] * _cosp_ecc + b_[i] * sinp ; // new location v_[i] = (-a_[i] * sinp + b_[i] * cosp) * de_dt; // direction of v only } } else // hyperbolic orbit // parabolic? { if(p1->is_elliptical) { fprintf(get_file(FILE_WARNING), "#### [t=%1.12e+%1.12e] Particle #%d thrown onto hyperbolic orbit with e=%e (E=%e, a=%e) ####\n", t_total(p1->t), convert_time(dt, 0), pos, ecc, p1->energy, convert_length(a, 0)); p1->is_elliptical = 0; } if(ecc == 1) fprintf(get_file(FILE_WARNING), "# # # %e\tParabolic orbit of m%d treated as hyperbolic: e=%e\t(x=%e)\n", t_total(p1->t), pos, ecc, convert_length(v_abs(p1->xp), 0)); // calculate eccentric anomaly e at t+dt e = (a + v_abs(r_)) / (ecc * a); if(e < 1.0) e = .0; else if(scal_prod(r_, v_) < 0) e = -acosh(e); else e = acosh(e); e = kepler(ecc, ecc * sinh(e) - e + dt * omega); cosp = cosh(e); sinp = sinh(e); de_dt = omega / (ecc * cosp - 1.); for(i = 0; i < DIMENSIONS; i++) { r_[i] = a_[i] * (ecc - cosp) + b_[i] * sinp; // new location v_[i] = (-a_[i] * sinp + b_[i] * cosp) * de_dt; // direction of v only } } // get |v_| from j_ = r_ x v_ v = v_abs(v_); r = v_abs(r_); v = v_abs(j_) / (r * v * sin(acos(scal_prod(r_, v_)/ (r * v)))); for(i = 0; i < DIMENSIONS; i++) { //v_[i] *= v; // total motion relative to fix central mass p1->xp[i] = p0->xp[i] + r_[i]; p1->vp[i] = p0->vp[i] + v_[i]; } if(out_a != NULL) { _1_r2 = 1. / scal_prod(r_, r_); afact = - m_c * _1_r2 * sqrt(_1_r2); //printf("4 %e %e %e\n", *(out_a), *(out_a+1), *(out_a+2)); for(i = 0; i < DIMENSIONS; i++) out_a[i] = afact * r_[i]; if(out_a_ != NULL) { v_r_ = scal_prod(v_, r_); for(i = 0; i < DIMENSIONS; i++) out_a_[i] = afact * (v_[i] - 3 * _1_r2 * v_r_ * r_[i]); if(out_a_2 != NULL) { v_v_ = scal_prod(v_, v_); r_a_ = scal_prod(r_, out_a); for(i = 0; i < DIMENSIONS; i++) out_a_2[i] = afact * (out_a[i] - 3. * _1_r2 * (v_r_ * (2. * v_[i] - 5. * v_r_ * r_[i] * _1_r2) + (v_v_ + r_a_) * r_[i])); if(out_a_3 != NULL) { v_a_ = scal_prod(v_, out_a); r_a__ = scal_prod(r_, out_a_); for(i = 0; i < DIMENSIONS; i++) out_a_3[i] = afact * (out_a_[i] - 3. * _1_r2 * (3. * v_r_ * out_a[i] + 3. * (v_v_ + r_a_) * (v_[i] - 5. * v_r_ * _1_r2 * r_[i]) + (3. * v_a_ + r_a__) * r_[i] + v_r_ * v_r_ * _1_r2 * (-15. * v_[i] + 35. * v_r_ * _1_r2 * r_[i]))); } } } } _exit_function(); }