dsblock5.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. /* Begin dsblock5.c */
  2. /* File version: 1.4, 1998-03-20 */
  3. /*
  4. * Copyright (C) 1997-2001 Dynasim AB.
  5. * All rights reserved.
  6. *
  7. */
  8. }
  9. #undef externalTable_
  10. #ifdef NBR_TASKS
  11. DYMOLA_STATIC int nbrTasks_=NBR_TASKS;
  12. #else
  13. DYMOLA_STATIC int nbrTasks_=0;
  14. #endif
  15. #if !defined(DYMOLA_DSPACE)
  16. DYMOLA_STATIC double
  17. DymolaStartTimers_[
  18. #ifdef NrDymolaTimers_
  19. NrDymolaTimers_ ? NrDymolaTimers_ : 1
  20. #else
  21. 1
  22. #endif
  23. ];
  24. DYMOLA_STATIC double DymolaTimeZero[100000]={0};
  25. DYMOLA_STATIC int DymolaTimeZeroLength=100000;
  26. #endif
  27. #if !defined(DymolaHaveUpdateInitVars)
  28. DYMOLA_STATIC void UpdateInitVars(double *time, double X_[], double XD_[], double U_[], \
  29. double DP_[], int IP_[], Dymola_bool LP_[], double F_[], double Y_[], double W_[], double QZ_[], double duser_[], int iuser_[], void*cuser_[], struct DYNInstanceData*did_)
  30. {
  31. return;
  32. }
  33. #endif
  34. /* Must be initialized (and thus defined) because moutil is included first*/
  35. static int DYNStrInit(struct DYNInstanceData*did_) {
  36. if (DYNX(DYNAuxStr_,0)==0) {
  37. int j;
  38. for(j=0;j<sizeof(DYNAuxStr_)/sizeof(*DYNAuxStr_);++j) DYNAuxStr_[j]=did_->DYNAuxStrBuff_vec+j*
  39. #if defined(MAXAuxStrLen_) && MAXAuxStrLen_>10
  40. MAXAuxStrLen_
  41. #else
  42. 10
  43. #endif
  44. ;
  45. }
  46. return 0;
  47. }
  48. DYMOLA_STATIC void DYNSetAuxString(struct DYNInstanceData*did_,const char*s,int i) {
  49. DYNStrInit(did_);
  50. if (i>=0 && i<sizeof(DYNAuxStr_)/sizeof(*DYNAuxStr_)) {
  51. int j,mlen=
  52. #if defined(MAXAuxStrLen_) && MAXAuxStrLen_>10
  53. MAXAuxStrLen_
  54. #else
  55. 10
  56. #endif
  57. ;
  58. for(j=0;j<mlen-1 && s[j];++j) DYNAuxStr_[i][j]=s[j];
  59. DYNAuxStr_[i][j]=0;
  60. if (s[j]) {DymosimMessage("Truncated string variable to");DymosimMessage(DYNAuxStr_[i]);}
  61. } else DymosimMessage("Internal error in String handling.");
  62. }
  63. DYMOLA_STATIC void DYNSetAuxStringArray(struct DYNInstanceData*did_,struct StringArray s,int i) {
  64. int nrElem,j;
  65. nrElem=StringNrElements(s);
  66. if (i>=0 && i+nrElem<=sizeof(DYNAuxStr_)/sizeof(*DYNAuxStr_)) {
  67. for(j=0;j<nrElem;++j) {
  68. DYNSetAuxString(did_,s.data[j],i+j);
  69. }
  70. } else DymosimMessage("Internal error in String array handling.");
  71. }
  72. DYMOLA_STATIC const char*DYNGetAuxStr(struct DYNInstanceData*did_,int i) {
  73. DYNStrInit(did_);
  74. if (i>=0 && i<sizeof(DYNAuxStr_)/sizeof(*DYNAuxStr_)) {
  75. return DYNAuxStr_[i];
  76. }
  77. return "";
  78. }
  79. static int QNLfunc_vec[QNLmax_ ? QNLmax_ : 1] = {0};
  80. DYMOLA_STATIC int* QNLfunc = QNLfunc_vec;
  81. static int QNLjac_vec[QNLmax_ ? QNLmax_ :1] = {0};
  82. DYMOLA_STATIC int* QNLjac = QNLjac_vec;
  83. DYMOLA_STATIC int QNLmax=QNLmax_;
  84. #if !defined(NExternalObject_)
  85. #define NExternalObject_ 10
  86. #endif
  87. static double delayID_vec[SizeDelay_?SizeDelay_:1] = {0};
  88. DYMOLA_STATIC double* delayID = delayID_vec;
  89. DYMOLA_STATIC double Buffersize = 20000;
  90. DYMOLA_STATIC int setDefault_=0;
  91. DYMOLA_STATIC int setDefaultX_=0,setDefaultU_=0,setDefaultY_=0,setDefaultP_=0,setDefaultDX_=0,setDefaultW_=0;
  92. DYMOLA_STATIC LIBDS_API_AFTER void delayDerivativeClose(void);
  93. DYMOLA_STATIC void delayBuffersCloseNew(struct DYNInstanceData*did_) {
  94. int i;
  95. for(i=0;i<SizeDelay_;++i) delayID[i]=0;
  96. for(i=0;i<MAXAux+10000;++i) Aux_[i]=0;
  97. for(i=0;i<SizePre_;++i) QPre_[i]=0;
  98. for(i=0;i<SizePre_;++i) RefPre_[i]=0;
  99. for(i=0;i<SizeEq_;++i) EqRemember2_[i]=EqRemember1_[i]=0;
  100. for(i=0;i<NWhen_;++i) QEvaluateNew_[i]=QEvaluate_[i]=0;
  101. for(i=0;i<NGlobalHelp_;++i) DYNhelp[i]=0;
  102. for(i=0;i<NGlobalHelpI_;++i) did_->helpvari_vec[i]=0;
  103. for(i=0;i<2*NRel_+1;++i)
  104. oldQZ2_[i]=oldQZ3_[i] = QZold_[i]=oldQZ_[i]=oldQZDummy_[i]=0;
  105. for(i=0;i<NRel_+1;++i) QRel_[i]=QM_[i]=Qn_[i] = Qp_[i]=Qscaled_[i]=0.0;
  106. for(i=0;i<NSamp_;++i) {NextSampleTime_[i]=NextSampleTimeNew_[i]=0;NextSampleAct_[i]=NextSampleActNew_[i]=0;}
  107. for(i=0;i<NRel_+1;++i) QL_[i]=Qenable_[i]=0;
  108. for(i=0;i<NTim_+1;++i) QTimed_[i]=0;
  109. EqRemember1Time_=-1e33;
  110. EqRemember2Time_=-1e33;
  111. for(i=NExternalObject_-1;i>=0;--i) {
  112. /* Reverse order in case of dependencies */
  113. void*x=did_->externalTable_vec[i].obj_;
  114. did_->externalTable_vec[i].obj_=0;
  115. if (x && did_->externalTable_vec[i].destructor_)
  116. (*(did_->externalTable_vec[i].destructor_))(x);
  117. did_->externalTable_vec[i].destructor_=0;
  118. }
  119. for(i=0;i<did_->DymolaTimerStructsLen_var;i++) {
  120. did_->DymolaTimerStructs_vec[i].num=0;
  121. }
  122. delayDerivativeClose();
  123. }
  124. DYMOLA_STATIC void delayBuffersClose(void) {
  125. delayBuffersCloseNew(&tempData);
  126. }
  127. DYMOLA_STATIC int dynInstanceDataSize() {
  128. return sizeof(struct DYNInstanceData);
  129. }
  130. DYMOLA_STATIC void CheckForEvents(struct DYNInstanceData*did_,double Time, int Init, int Event,
  131. double QZ_[], int nrel_, double F_[], int nx_,double*duser_,int*iuser_)
  132. /* SCRAMBLE ON */
  133. {
  134. #define DebugCheckForEvents 0
  135. #define OvershootFactor 1.2
  136. /* */
  137. #define FindLastEvent 1
  138. /* */
  139. #define CheckForEventsEps 1e-10
  140. /* */
  141. #define SecondDegreeOvershootFactor 1.04
  142. #define SecondDegreeUncertainty 0.4
  143. #define SecondDegreeUncertainty2 0.7
  144. int ZZZ715,ZZZ39; static double oldTime,oldDummyTime=-1e30;
  145. static double oldTime2, oldDummyTime2, oldstepSizeRatio;
  146. static double c1, c2, c1start; static double T1end=-1e30; static double T2end=-1e30, stepSizeRatio=1; double ZZZ8329, ZZZ7652;
  147. #ifdef InterpolateStatesForInline
  148. static const double CheckForEventsMinStep=0.2;
  149. #else
  150. static const double CheckForEventsMinStep=0;
  151. #endif
  152. int ZZZ5998; if (Init) {
  153. #if defined(FindEvent_)
  154. DymosimMessage("");
  155. DymosimMessage("Approximative event finder used. Must be used with Euler method."); DymosimMessage("");
  156. #endif
  157. StepSize = 0; LastTime = 1E30; T1end = -1E30; T2end = -1E30; oldTime = Time; oldDummyTime = -1e30;
  158. #if SecondDegree
  159. oldTime2 = oldDummyTime2 = Time; oldstepSizeRatio = 1.0;
  160. #endif
  161. c1=1; c2=1; c1start=1; stepSizeRatio=1; } if (StepSize == 0 && Time > LastTime) StepSize = Time - LastTime;
  162. if (Event) LastTime = Time; ZZZ5998 = Time>oldDummyTime; if (ZZZ5998) {
  163. #if SecondDegree
  164. oldTime2=oldTime; oldDummyTime2=oldDummyTime; oldstepSizeRatio=stepSizeRatio;
  165. if (StepSize!=0) { if (Time>=T1end && Time<T2end) stepSizeRatio = (T1end-oldTime)/StepSize; else stepSizeRatio = (Time-oldTime)/StepSize; } for (ZZZ715 = 0; ZZZ715 < 2*nrel_;ZZZ715++) {oldQZ3_[ZZZ715]=oldQZ2_[ZZZ715];oldQZ2_[ZZZ715]=oldQZ_[ZZZ715];}
  166. #endif
  167. for(ZZZ715=0;ZZZ715<2*nrel_;ZZZ715++) oldQZ_[ZZZ715]=oldQZDummy_[ZZZ715]; }
  168. { for(ZZZ715=0;ZZZ715<2*nrel_;ZZZ715++) oldQZDummy_[ZZZ715]=Qenable_[ZZZ715/2+1] ? QZ_[ZZZ715] : 0; } if (StepSize!=0 && ZZZ5998) { double ZZZ1317=0;
  169. #if DebugCheckForEvents
  170. for (ZZZ715 = 0; ZZZ715 < 2*nrel_; ZZZ715++) { if (Qenable_[ZZZ715/2+1]) { if (oldQZ_[ZZZ715]*QZ_[ZZZ715]<0) {
  171. double ZZZ8860; ZZZ8860=QZ_[ZZZ715]/(QZ_[ZZZ715]-oldQZ_[ZZZ715]); if (ZZZ8860>ZZZ1317) {ZZZ1317=ZZZ8860;ZZZ39=ZZZ715/2;} } } } if (ZZZ1317>0) { char ZZZ732[200]; if (Time<T2end) { sprintf(ZZZ732,"Event at projected time %.10g overshoot %.10g",T1end,c1*ZZZ1317+1);
  172. } else if (stepSizeRatio>1+CheckForEventsEps || stepSizeRatio<1-CheckForEventsEps) { sprintf(ZZZ732,"Missed event at time %.10g interpolated at %.10g",Time,Time-ZZZ1317*stepSizeRatio*StepSize); } else { sprintf(ZZZ732,"Event at time %.10g interpolated at %.10g",Time,Time-ZZZ1317*StepSize); } DymosimMessage(ZZZ732);
  173. #if SecondDegree
  174. sprintf(ZZZ732,"Relation %d QZ=%.10g %.10g oldQZ=%.10g oldQZ2=%.10g oldQZ3=%.10g",ZZZ39,QZ_[2*ZZZ39],QZ_[2*ZZZ39+1],oldQZ_[2*ZZZ39],oldQZ2_[2*ZZZ39],oldQZ3_[2*ZZZ39]);
  175. #else
  176. sprintf(ZZZ732,"Relation %d QZ=%.10g %.10g oldQZ=%.10g",ZZZ39,QZ_[2*ZZZ39],QZ_[2*ZZZ39+1],oldQZ_[2*ZZZ39]);
  177. #endif
  178. DymosimMessage(ZZZ732); }
  179. #endif
  180. } if (StepSize != 0 && Time >= T2end) { c1 = c1start = FindLastEvent ? 0 :2; ZZZ7652 = (NextTimeEvent-Time)/StepSize; /* */
  181. ZZZ39=-1; if (ZZZ7652>0 && ZZZ7652<2 && (FindLastEvent ? ZZZ7652>c1: ZZZ7652<c1)) { c1=ZZZ7652; } for (ZZZ715 = 0; ZZZ715 < 2*nrel_; ZZZ715++) { ZZZ8329 = (QZ_[ZZZ715] - oldQZ_[ZZZ715])/stepSizeRatio; if (QZ_[ZZZ715] * (OvershootFactor*ZZZ8329*2 + QZ_[ZZZ715]) < 0 && Qenable_[ZZZ715/2+1] && QZ_[2*(ZZZ715/2)]*QZ_[2*(ZZZ715/2)+1]>0 ) { /* */ ZZZ7652 = -QZ_[ZZZ715]/ZZZ8329+(OvershootFactor-1); /* */
  182. #if SecondDegree
  183. if (oldDummyTime2>-1e30 && (oldQZ_[ZZZ715]>0 ? oldQZ2_[ZZZ715]>oldQZ_[ZZZ715] : oldQZ2_[ZZZ715]<oldQZ_[ZZZ715])) { /* */ double ZZZ3419, ZZZ8687, ZZZ4213, ZZZ2231, ZZZ4006, ZZZ6591, ZZZ5281, ZZZ8430, ZZZ7134; ZZZ3419=QZ_[ZZZ715]; ZZZ8687=(stepSizeRatio+oldstepSizeRatio); ZZZ4213=stepSizeRatio*ZZZ8687*oldstepSizeRatio; ZZZ2231=(ZZZ8687*ZZZ8687*(oldQZ_[ZZZ715]-ZZZ3419)-stepSizeRatio*stepSizeRatio*(oldQZ2_[ZZZ715]-ZZZ3419))/ZZZ4213; ZZZ4006=(-ZZZ8687*(oldQZ_[ZZZ715]-ZZZ3419)+stepSizeRatio*(oldQZ2_[ZZZ715]-ZZZ3419))/ZZZ4213; ZZZ6591=4*ZZZ3419*ZZZ4006; ZZZ5281=ZZZ2231*ZZZ2231;
  184. ZZZ8430=(oldQZ_[ZZZ715]>0 ? oldQZ3_[ZZZ715]>oldQZ2_[ZZZ715] : oldQZ3_[ZZZ715]<oldQZ2_[ZZZ715]) ? SecondDegreeUncertainty : SecondDegreeUncertainty2; ZZZ7134=ZZZ5281-(ZZZ6591>0 ? ZZZ6591*(1+ZZZ8430) : ZZZ6591*(1-ZZZ8430)); if (ZZZ7134>=0) { double ZZZ5803; ZZZ5803=-(2*ZZZ3419/(-ZZZ2231-(ZZZ2231>0?1:-1)*sqrt(ZZZ7134)))+(SecondDegreeOvershootFactor-1);
  185. #if DebugCheckForEvents
  186. {char ZZZ732[200]; sprintf(ZZZ732,"%d ZZZ3419 %.10g ZZZ8687 %.10g ZZZ4213 %.10g ZZZ2231 %.10g ZZZ7652 %.10g ZZZ7134 %.10g",ZZZ715,ZZZ3419,ZZZ8687,ZZZ4213,ZZZ2231,ZZZ4006,ZZZ7134); DymosimMessage(ZZZ732);
  187. sprintf(ZZZ732,"C1: %g C2: %g beta=-%g alpha=-%g QZ=%.10g oldQZ=%.10g oldQZ2=%.10g",ZZZ7652,ZZZ5803,stepSizeRatio+oldstepSizeRatio,stepSizeRatio, QZ_[ZZZ715],oldQZ_[ZZZ715],oldQZ2_[ZZZ715]); DymosimMessage(ZZZ732); }
  188. #endif
  189. if (ZZZ5803>-0.5 && ZZZ5803 < 2.5) ZZZ7652=ZZZ5803; } }
  190. #endif
  191. if (ZZZ7652 > 0 && ZZZ7652<2 && (FindLastEvent ? ZZZ7652>c1: ZZZ7652<c1)) { /* */
  192. c1 = ZZZ7652; /* */ZZZ39=ZZZ715/2; } } } if (c1 != 1E30 && c1 != c1start && c1<1+CheckForEventsMinStep) { /* */ if (c1<CheckForEventsMinStep) c1=CheckForEventsMinStep; c2 = 2 - c1;
  193. T1end = Time + (1-CheckForEventsEps)*StepSize; T2end = Time + (2-CheckForEventsEps)*StepSize; /* */
  194. #if DebugCheckForEvents
  195. {char ZZZ732[200]; sprintf(ZZZ732,"Project at %.10g to %.10g Short %.10g Long %.10g",Time,T1end,c1*StepSize,c2*StepSize); DymosimMessage(ZZZ732);} {char ZZZ732[200];
  196. #if SecondDegree
  197. sprintf(ZZZ732,"Relation %d QZ=%.10g %.10g oldQZ=%.10g oldQZ2=%.10g oldQZ3=%.10g",ZZZ39,QZ_[2*ZZZ39],QZ_[2*ZZZ39+1],oldQZ_[2*ZZZ39],oldQZ2_[2*ZZZ39],oldQZ3_[2*ZZZ39]);
  198. #else
  199. sprintf(ZZZ732,"Relation %d QZ=%.10g %.10g oldQZ=%.10g",ZZZ39,QZ_[2*ZZZ39],QZ_[2*ZZZ39+1],oldQZ_[2*ZZZ39]);
  200. #endif
  201. DymosimMessage(ZZZ732); }
  202. #endif
  203. } else { c2=1; T2end=Time; T1end=Time; }
  204. } oldTime=oldDummyTime=Time; currentStepSize_ = StepSize;
  205. #ifdef InterpolateStatesForInline
  206. currentStepSizeRatio_ = 1;
  207. #endif
  208. currentStepSizeRatio2_ = 1; if (Time < T1end) {
  209. currentStepSizeRatio2_ = c1;
  210. #ifdef InterpolateStatesForInline
  211. currentStepSizeRatio_ = c1;
  212. #else
  213. currentStepSize_ = c1*StepSize;
  214. #endif
  215. for (ZZZ715 = 0; ZZZ715 < nx_; ZZZ715++) { F_[ZZZ715] = F_[ZZZ715]*c1; } /* */
  216. } else if (Time < T2end) { currentStepSizeRatio2_ = c2;
  217. #ifdef InterpolateStatesForInline
  218. currentStepSizeRatio_ = c2;
  219. #else
  220. currentStepSize_ = c2*StepSize;
  221. #endif
  222. for (ZZZ715 = 0; ZZZ715 < nx_; ZZZ715++) { F_[ZZZ715] = F_[ZZZ715]*c2; }
  223. /* */ oldTime=T1end; }}
  224. /* SCRAMBLE OFF */
  225. DYMOLA_STATIC Dymola_bool sampleFunction(struct DYNInstanceData*did_,double Time, double start, double interval, int counter,
  226. Dymola_bool Init, Dymola_bool Event) {
  227. struct BasicDDymosimStruct*basicD=getBasicDDymosimStruct();
  228. Dymola_bool samp = false;
  229. if (Init || (Event && NextSampleAct_[counter]==0)) {
  230. double x;
  231. basicD->mOrigTimeError=Dymola_max(basicD->mOrigTimeError,fabs(start)); /* Collect them */
  232. x=findCounter(Dymola_max(Time,start),start,interval);
  233. if (Init || x>NextSampleTime_[counter])
  234. NextSampleTime_[counter]=x;
  235. /* Samples at start,start+interval,...*/
  236. /* Replace Dymola_max(Time,start) by Time to sample at ...,start-interval,start,start+interval */
  237. };
  238. if (Event) {
  239. double eventTime=start+(NextSampleTime_[counter]-1)*interval;
  240. const double eventAccuracy=
  241. #ifndef DynSimStruct
  242. 5e-14
  243. #else
  244. 1e-7
  245. #endif
  246. *(fabs(Time)+basicD->mOrigTimeError);
  247. /* 5*eps to guard against different times */
  248. /*DymosimMessageDouble("Event at time: ",Time);*/
  249. /*DymosimMessageDouble("Event Time:",eventTime);*/
  250. while (eventTime<=Time+eventAccuracy) {
  251. NextSampleTime_[counter]+=1;
  252. eventTime=start+(NextSampleTime_[counter]-1)*interval;
  253. /*DymosimMessageDouble("Sampling at time: ", Time);*/
  254. /*DymosimMessageDouble("Next sampling",eventTime);*/
  255. samp = true;
  256. }
  257. NextSampleTimeNew_[counter]=NextSampleTime_[counter];
  258. NextSampleActNew_[counter]=1;
  259. registerTimeEventNew(eventTime, did_); /* The next event for this sampler */
  260. }
  261. return samp;
  262. }
  263. DYMOLA_STATIC Dymola_bool sampleFunctionM(struct DYNInstanceData*did_,double Time, double start, double interval, int counter,
  264. Dymola_bool Init, Dymola_bool Event) {
  265. struct BasicDDymosimStruct*basicD=getBasicDDymosimStruct();
  266. Dymola_bool samp = false;
  267. if (interval<=0) DymosimError("Sample did not have positive sample interval");
  268. if (Init|| (Event && NextSampleTime_[counter]==0)) {
  269. double x;
  270. if (Init==2) return false;
  271. basicD->mOrigTimeError=Dymola_max(basicD->mOrigTimeError,fabs(start)); /* Collect them */
  272. x=findCounter(Dymola_max(Time,start),start,interval);
  273. if (Init || x>NextSampleTime_[counter])
  274. NextSampleTime_[counter]=x;
  275. /* Samples at start,start+interval,...*/
  276. /* Replace Dymola_max(Time,start) by Time to sample at ...,start-interval,start,start+interval */
  277. };
  278. if (Event) {
  279. double eventTime=start+(NextSampleTime_[counter]-1)*interval;
  280. const double eventAccuracy=
  281. #ifndef DynSimStruct
  282. 5e-14
  283. #else
  284. 1e-7
  285. #endif
  286. *(fabs(Time)+basicD->mOrigTimeError);
  287. /* 5*eps to guard against different times */
  288. /*DymosimMessageDouble("Event at time: ",Time);*/
  289. /*DymosimMessageDouble("Event Time:",eventTime);*/
  290. NextSampleTimeNew_[counter]=NextSampleTime_[counter];
  291. while (eventTime<=Time+eventAccuracy) {
  292. NextSampleTimeNew_[counter]+=1;
  293. eventTime=start+(NextSampleTimeNew_[counter]-1)*interval;
  294. /*DymosimMessageDouble("Sampling at time: ", Time);*/
  295. /*DymosimMessageDouble("Next sampling",eventTime);*/
  296. samp = true;
  297. }
  298. NextSampleActNew_[counter]=1;
  299. registerTimeEventNew(eventTime, did_); /* The next event for this sampler */
  300. }
  301. return samp;
  302. }
  303. DYMOLA_STATIC Dymola_bool sampleFunctionM3(struct DYNInstanceData*did_,double Time, double start, double interval, int phase, int maxVal, int counter,
  304. Dymola_bool Init, Dymola_bool Event) {
  305. struct BasicDDymosimStruct*basicD=getBasicDDymosimStruct();
  306. double x,x2;
  307. Dymola_bool samp = false;
  308. if (interval<=0 || maxVal<=0) DymosimError("Sample did not have positive sample interval");
  309. if (Init|| (Event && NextSampleTime_[counter]==0)) {
  310. if (Init==2) return false;
  311. basicD->mOrigTimeError=Dymola_max(basicD->mOrigTimeError,fabs(start)); /* Collect them */
  312. x=findCounter(Dymola_max(Time,start),start,interval);
  313. if (Init || x>NextSampleTime_[counter])
  314. NextSampleTime_[counter]=x;
  315. /* Samples at start,start+interval,...*/
  316. /* Replace Dymola_max(Time,start) by Time to sample at ...,start-interval,start,start+interval */
  317. };
  318. if (Event) {
  319. double eventTime=start+(NextSampleTime_[counter]-1)*interval;
  320. const double eventAccuracy=
  321. #ifndef DynSimStruct
  322. 5e-14
  323. #else
  324. 1e-7
  325. #endif
  326. *(fabs(Time)+basicD->mOrigTimeError);
  327. /* 5*eps to guard against different times */
  328. /*DymosimMessageDouble("Event at time: ",Time);*/
  329. /*DymosimMessageDouble("Event Time:",eventTime);*/
  330. NextSampleTimeNew_[counter]=NextSampleTime_[counter];
  331. while (eventTime<=Time+eventAccuracy) {
  332. NextSampleTimeNew_[counter]+=1;
  333. eventTime=start+(NextSampleTimeNew_[counter]-1)*interval;
  334. /*DymosimMessageDouble("Sampling at time: ", Time);*/
  335. /*DymosimMessageDouble("Next sampling",eventTime);*/
  336. samp=true;
  337. }
  338. x=floor((0.1+NextSampleTimeNew_[counter]-2-(maxVal-1-phase))/maxVal); /* the passed point */
  339. x2=x*maxVal+(maxVal-1-phase);
  340. samp=samp && (x2==(NextSampleTimeNew_[counter]-2)) && x>=0; /* Handle negative phase */
  341. eventTime=start+(x2+maxVal)*interval;
  342. NextSampleActNew_[counter]=1;
  343. registerTimeEventNew(eventTime, did_); /* The next event for this sampler */
  344. }
  345. return samp;
  346. }
  347. #if defined(DYMOSIM) && defined(NI_)
  348. LIBDS_API void InitI2(int, int, double*,int*);
  349. static void InitI(struct DYNInstanceData* did_,int n,int d) {
  350. InitI2(n, d, QImd_, QIml_);
  351. }
  352. #else
  353. static void InitI(struct DYNInstanceData* did_,int n,int d) {
  354. ;
  355. }
  356. #endif
  357. DYMOLA_STATIC void ClearNextSample(struct DYNInstanceData* did_) {
  358. int i;
  359. for(i=0;i<NSamp_;++i) NextSampleActNew_[i]=0;
  360. }
  361. #if defined(DIRECT_FEED_THROUGH)
  362. DYMOLA_STATIC int DirectFeedThrough_=1;
  363. #else
  364. DYMOLA_STATIC int DirectFeedThrough_=0;
  365. #endif
  366. #if DymolaUseRDTSC_
  367. static double rtdrealFrequency=1.0e9;
  368. static double rtdinvFreq=1.0/1.0e9;
  369. struct MyLargeInteger {
  370. unsigned int LowPart;
  371. unsigned int HighPart;
  372. };
  373. static const double MInt=4294967296.0;
  374. static double DymolaPerformance(double*d,int i) {
  375. struct MyLargeInteger count={0,0};
  376. if (sizeof(struct MyLargeInteger)!=sizeof(*d))
  377. return -1;
  378. {
  379. #if defined(_MSC_VER) && defined(_M_IX86)
  380. __asm {
  381. rdtsc
  382. mov count.LowPart, eax
  383. mov count.HighPart, edx
  384. }
  385. #elif defined(__GNUC__)
  386. /* Gnu assembler: other names of registers, declare that rdtsc clobbers registers
  387. and different order of operands */
  388. __asm("rdtsc" : /* none */ : : "eax", "edx" );
  389. __asm("mov %%eax, %0" : "=g" (count.LowPart));
  390. __asm("mov %%edx, %0" : "=g" (count.HighPart));
  391. #elif defined(__LCC__)
  392. /* Lcc, default in Matlab, has it as an intrinsic function */
  393. extern long long _stdcall _rdtsc(void);
  394. {
  395. *(long long*)(&count)=_rdtsc();
  396. }
  397. #endif
  398. }
  399. if (i==0) {
  400. if (d) *(struct MyLargeInteger*)(d)=count;
  401. return count.LowPart+count.HighPart*MInt;
  402. } else {
  403. struct MyLargeInteger*a=(struct MyLargeInteger*)(d);
  404. return (
  405. (count.HighPart*1.0-a->HighPart)*MInt+count.LowPart-a->LowPart)*rtdinvFreq;
  406. }
  407. }
  408. struct RegisterReturn {
  409. int EAXV1,EBXV1,ECXV1,EDXV1;
  410. int EAXV2,EBXV2,ECXV2,EDXV2;
  411. int EAXV3,EBXV3,ECXV3,EDXV3;
  412. };
  413. static void InitializeFrequency(double d) {
  414. static int firstCall=1;
  415. if (!firstCall) return;
  416. firstCall=0;
  417. if (d==0) {
  418. unsigned int x=0x80000000UL;
  419. union {
  420. struct RegisterReturn registerReturn;
  421. char ch[48];
  422. } myValues;
  423. myValues.ch[0]='\0';
  424. #if defined(_MSC_VER) && defined(_M_IX86)
  425. _asm {
  426. mov eax, x
  427. cpuid
  428. mov x, eax
  429. }
  430. #elif defined(__GNUC__) && defined(i386)
  431. __asm("mov %0, %%eax": /*none */: "g" (x));
  432. __asm("cpuid");
  433. __asm("mov %%eax, %0" : "=g" (x));
  434. #endif
  435. if (x>=0x80000004UL) {
  436. x=0x80000002UL;
  437. #if defined(_MSC_VER) && defined(_M_IX86)
  438. _asm {
  439. mov eax, x
  440. cpuid
  441. mov myValues.registerReturn.EAXV1, eax
  442. mov myValues.registerReturn.EBXV1, ebx
  443. mov myValues.registerReturn.ECXV1, ecx
  444. mov myValues.registerReturn.EDXV1, edx
  445. }
  446. #elif defined(__GNUC__) && defined(i386)
  447. __asm("mov %0, %%eax": : "g" (x));
  448. __asm("cpuid" : : : "eax", "ebx", "ecx", "edx");
  449. __asm("mov %%eax, %0": "=g" (myValues.registerReturn.EAXV1));
  450. __asm("mov %%ebx, %0": "=g" (myValues.registerReturn.EBXV1));
  451. __asm("mov %%ecx, %0": "=g" (myValues.registerReturn.ECXV1));
  452. __asm("mov %%edx, %0": "=g" (myValues.registerReturn.EDXV1));
  453. #endif
  454. x=0x80000003UL;
  455. #if defined(_MSC_VER) && defined(_M_IX86)
  456. _asm {
  457. mov eax, x
  458. cpuid
  459. mov myValues.registerReturn.EAXV2, eax
  460. mov myValues.registerReturn.EBXV2, ebx
  461. mov myValues.registerReturn.ECXV2, ecx
  462. mov myValues.registerReturn.EDXV2, edx
  463. }
  464. #elif defined(__GNUC__) && defined(i386)
  465. __asm("mov %0, %%eax": : "g" (x));
  466. __asm("cpuid" : : : "eax", "ebx", "ecx", "edx");
  467. __asm("mov %%eax, %0": "=g" (myValues.registerReturn.EAXV2));
  468. __asm("mov %%ebx, %0": "=g" (myValues.registerReturn.EBXV2));
  469. __asm("mov %%ecx, %0": "=g" (myValues.registerReturn.ECXV2));
  470. __asm("mov %%edx, %0": "=g" (myValues.registerReturn.EDXV2));
  471. #endif
  472. x=0x80000004UL;
  473. #if defined(_MSC_VER) && defined(_M_IX86)
  474. _asm {
  475. mov eax, x
  476. cpuid
  477. mov myValues.registerReturn.EAXV3, eax
  478. mov myValues.registerReturn.EBXV3, ebx
  479. mov myValues.registerReturn.ECXV3, ecx
  480. mov myValues.registerReturn.EDXV3, edx
  481. }
  482. #elif defined(__GNUC__) && defined(i386)
  483. __asm("mov %0, %%eax": : "g" (x));
  484. __asm("cpuid" : : : "eax", "ebx", "ecx", "edx");
  485. __asm("mov %%eax, %0": "=g" (myValues.registerReturn.EAXV3));
  486. __asm("mov %%ebx, %0": "=g" (myValues.registerReturn.EBXV3));
  487. __asm("mov %%ecx, %0": "=g" (myValues.registerReturn.ECXV3));
  488. __asm("mov %%edx, %0": "=g" (myValues.registerReturn.EDXV3));
  489. #endif
  490. {
  491. double dMult=1e6;
  492. char*lastM=strrchr(myValues.ch,'M');
  493. if (lastM!=0 && lastM[1]=='H' && lastM[2]=='z') {
  494. } else {
  495. lastM=strrchr(myValues.ch,'G');
  496. if (lastM!=0 && lastM[1]=='H' && lastM[2]=='z') {
  497. dMult=1e9;
  498. } else lastM=0;
  499. }
  500. if (lastM!=0) {
  501. for(;lastM>myValues.ch && lastM[-1]==' ';lastM--);
  502. for(;lastM>myValues.ch && (lastM[-1]>='0' && lastM[-1]<='9' || lastM[-1]=='.');lastM--);
  503. if (sscanf(lastM,"%lg",&d)!=1) {
  504. d=0;
  505. } else d*=dMult;
  506. }
  507. }
  508. }
  509. if (d==0) {
  510. char str[200];
  511. sprintf(str,"Could not determine speed of processor. Assuming 1GHz\nCPU reported: %s\n",myValues.ch);
  512. DymosimMessage(str);
  513. d=1e9;
  514. } else {
  515. char str[200];
  516. sprintf(str,"Determined processor speed to %lg MHz\nCPU reported: %s\n",d/1e6,myValues.ch);
  517. DymosimMessage(str);
  518. }
  519. }
  520. rtdrealFrequency=d;
  521. rtdinvFreq=1.0/rtdrealFrequency;
  522. {
  523. extern double (*DymolaTimerCounterCallback)(double*,int);
  524. DymolaTimerCounterCallback=&DymolaPerformance;
  525. }
  526. }
  527. #if defined(DymolaUseRDTSCFrequency_)
  528. #define SetupProcessorCounter() InitializeFrequency(DymolaUseRDTSCFrequency_)
  529. #else
  530. #define SetupProcessorCounter() InitializeFrequency(0.0)
  531. #endif
  532. #else
  533. #define SetupProcessorCounter()
  534. #endif
  535. DYMOLA_STATIC void GetDimensions(int *nx_, int *nx2_, int *nu_, int *ny_, int *nw_, int *np_,
  536. int *nrel_, int *ncons_, int *dae_)
  537. {
  538. *nx_ = NX_;
  539. *nx2_ = NX2_;
  540. *nu_ = NU_;
  541. *ny_ = NY_;
  542. *nw_ = NW_;
  543. *np_ = NP_;
  544. *nrel_ = NRel_;
  545. *ncons_ = NCons_;
  546. *dae_ = DAEsolver_;
  547. #if defined(DynSimStruct)
  548. SetupProcessorCounter();
  549. #endif
  550. }
  551. DYMOLA_STATIC void GetDimensions2(int *nx_, int *nx2_, int *nu_, int *ny_, int *nw_, int *np_, int* nsp_,
  552. int*nrel2_,int *nrel_, int *ncons_, int *dae_)
  553. {
  554. *nx_ = NX_;
  555. *nx2_ = NX2_;
  556. *nu_ = NU_;
  557. *ny_ = NY_;
  558. *nw_ = NW_;
  559. #ifdef NPS_
  560. *nsp_ = NPS_;
  561. #else
  562. *nsp_ = 0;
  563. #endif
  564. *np_ = NP_;
  565. *nrel_ = NRel_;
  566. #ifdef NRelF_
  567. *nrel2_ = NRelF_;
  568. #else
  569. *nrel2_ = NRel_;
  570. #endif
  571. *ncons_ = NCons_;
  572. *dae_ = DAEsolver_;
  573. #if defined(DynSimStruct)
  574. SetupProcessorCounter();
  575. #endif
  576. }
  577. static int nx_=NX_;
  578. static int nx2_=NX2_;
  579. static int nu_=NU_;
  580. static int ny_=NY_;
  581. static int nw_=NW_;
  582. static int np_=NP_;
  583. #ifdef NPS_
  584. static int nsp_=NPS_;
  585. #else
  586. static int nsp_=0;
  587. #endif
  588. #ifdef NRelF_
  589. static int nrel2_=NRelF_;
  590. #else
  591. static int nrel2_=NRel_;
  592. #endif
  593. static int nrel_=NRel_;
  594. static int ncons_=NCons_;
  595. static int dae_=DAEsolver_;
  596. DYMOLA_STATIC void GetDimensions3(int *nrel_, int *ntim_, int *ncheckif_, int *nsamp_, int *nwhen_, int *nglobalhelp_,
  597. int *maxaux, int *qnlmax_, int *sizepre_, int *sizeeq_)
  598. {
  599. *nrel_ = NRel_;
  600. *ntim_ = NTim_;
  601. *ncheckif_ = NCheckIf_;
  602. *nsamp_ = NSamp_;
  603. *nwhen_ = NWhen_;
  604. *nglobalhelp_ = NGlobalHelp_;
  605. *maxaux = MAXAux;
  606. *qnlmax_ = QNLmax_;
  607. *sizepre_ = SizePre_;
  608. *sizeeq_ = SizeEq_;
  609. }
  610. DYMOLA_STATIC void UpdateDaeF_(Dymola_bool Init, double F_[], double XD_[])
  611. /* Calculate residue = f(x) - der(x)
  612. When intializing also: der(x) = f(x) */
  613. {
  614. int i_;
  615. double derx_;
  616. if (DAEsolver_)
  617. for (i_=0; i_<NX_; i_++) {
  618. derx_ = F_[i_];
  619. F_[i_] = derx_ - XD_[i_];
  620. if (Init)
  621. XD_[i_] = derx_;
  622. }
  623. }
  624. DYMOLA_STATIC void InitializeDymosimStruct(struct BasicDDymosimStruct*basicD,struct BasicIDymosimStruct*basicI) {
  625. #if INLINE_INTEGRATION
  626. basicI->mInlineIntegration=INLINE_INTEGRATION;
  627. #else
  628. basicI->mInlineIntegration=0;
  629. #endif
  630. #if defined(DymolaGeneratedFixedStepSize_)
  631. basicD->mDymolaFixedStepSize=DymolaGeneratedFixedStepSize_;
  632. #else
  633. basicD->mDymolaFixedStepSize=0.0;
  634. #endif
  635. basicD->mCurrentStepSizeRatio2 = 1.0;
  636. basicD->mOrigTimeError=0;
  637. }
  638. #if defined(RT) || defined(NRT)
  639. #else
  640. DYMOLA_STATIC int dsblockb_(const int *iopt_, int info_[], int sig_[], int dim_[],
  641. double *t0_, double x0_[], double xd0_[],
  642. double dp_[], int ip_[], Dymola_bool lp_[],
  643. double duser_[], int iuser_[], void*cuser_[],
  644. int *QiErr)
  645. {
  646. int c1_, c2_, c3_, i_, nx2_;
  647. double d1_;
  648. *(GlobalErrorPointer())=0;
  649. if (DAEsolver_)
  650. nx2_ = NX2_;
  651. else
  652. nx2_ = 0;
  653. if (*iopt_ == 1) {
  654. } else if (*iopt_ == 2) {
  655. SetupProcessorCounter();
  656. if (NCons_ > 0)
  657. info_[0] = 2;
  658. else if (DAEsolver_)
  659. info_[0] = 1;
  660. #if defined(HaveDummyDerivative_)
  661. info_[1] = 1;
  662. #endif
  663. #if defined(AnalyticJacobian_)
  664. info_[2] = AnalyticJacobianElements_;
  665. #endif
  666. /* if (NRel_ > 0 && NX_ + nx2_ == 0) */
  667. if (NX_ + nx2_ == 0)
  668. sig_[0] = 1; /* To enable handling of "state events" without states. */
  669. else
  670. sig_[0] = NX_ + nx2_;
  671. sig_[1] = NU_;
  672. sig_[2] = NY_;
  673. if (NRel_ > 0 && RootFinder_)
  674. sig_[3] = 1;
  675. sig_[4] = NW_;
  676. sig_[5] = NP_;
  677. sig_[6] = NA_; /* Number of alias signal matrices or scalars */
  678. sig_[7] = NA_; /* Total number of alias elements */
  679. /* if (NRel_ > 0 && NX_ + nx2_ == 0) */
  680. if (NX_ + nx2_ == 0)
  681. dim_[0] = 1;
  682. else
  683. dim_[0] = NX_ + nx2_;
  684. dim_[1] = NU_;
  685. dim_[2] = NY_;
  686. dim_[3] = 2 * NRel_;
  687. dim_[4] = NW_;
  688. dim_[5] = NP_;
  689. dim_[6] = NRelF_;
  690. dim_[7] = SizeEq_;
  691. dim_[9] = NHash1_;
  692. dim_[10] = NHash2_;
  693. dim_[11] = NX_;
  694. dim_[12] = nx2_;
  695. dim_[13] = NGlobalHelp_;
  696. dim_[14] = NHash3_;
  697. #ifdef NPS_
  698. dim_[15] = NPS_;
  699. #endif
  700. dim_[8] = dim_[0] + dim_[2] + dim_[3]*sig_[3] + dim_[4] + sizeof(struct BasicDDymosimStruct)/sizeof(doublereal);
  701. } else if (*iopt_ == 3) {
  702. iuser_[0] = NX_ + nx2_ + NCons_;
  703. iuser_[1] = NY_;
  704. iuser_[2] = NW_;
  705. iuser_[3] = 2 * NRel_;
  706. InitializeDymosimStruct((struct BasicDDymosimStruct*)(duser_+
  707. iuser_[0]+iuser_[1]+iuser_[2]+iuser_[3]),(struct BasicIDymosimStruct*)(iuser_+4));
  708. /* if (NRel_ > 0 && NX_ + nx2_ == 0) */
  709. declareNew_(x0_, dp_, 0, cuser_, QiErr, 0, (struct DeclarePhase*)0);
  710. }
  711. else if (*iopt_ == 4) {
  712. declareNew_(x0_,dp_,0,cuser_,QiErr, 1, (struct DeclarePhase*)0);
  713. } else if (*iopt_ == 5) {
  714. InitializeDymosimStruct((struct BasicDDymosimStruct*)(duser_),(struct BasicIDymosimStruct*)(iuser_));
  715. }
  716. leave:
  717. if (*(GlobalErrorPointer()) != 0)
  718. *QiErr = *(GlobalErrorPointer());
  719. return 0;
  720. }
  721. #endif
  722. #if defined(AnalyticJacobian_) && defined(AnalyticJacobianBCD_)
  723. DYMOLA_STATIC int QJacobianDefined_=1;
  724. #else
  725. DYMOLA_STATIC int QJacobianDefined_=0;
  726. #endif
  727. #if !defined(QJacobianCGDef_)
  728. DYMOLA_STATIC int QJacobianCG_[1]={0};
  729. DYMOLA_STATIC int QJacobianGC_[1]={0};
  730. DYMOLA_STATIC double QJacobianCD_[1]={0};
  731. #endif
  732. /* vector to hold FMI value references for possible continuous time states*/
  733. #if !defined(FMIStateValueReferencesDef_)
  734. DYMOLA_STATIC unsigned int FMIStateValueReferences_[1]={~0};
  735. #endif
  736. /* End dsblock5.c */