dsblock4.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /* Begin file dsblock4.c */
  2. /* File version: 1.7, 1999-01-20 */
  3. /*
  4. * Copyright (C) 1997-2001 Dynasim AB.
  5. * All rights reserved.
  6. *
  7. */
  8. /* end */
  9. }
  10. if (DymolaOneIteration_==-1) DymolaOneIteration_=0;
  11. if (did_->DymolaEventOptional_var && *idemand_==4 && Iter==2 && RootFinder_) {
  12. int i1_;
  13. for(i1_=0;i1_<nrel_*2;i1_++) {
  14. if (QZold_[i1_]*QZ_[i1_]<0)
  15. AnyEvent_=true;
  16. }
  17. if (AnyEvent_) {
  18. *idemand_=5;
  19. DYNEvent=true;
  20. Iter=0;
  21. goto iterateEvent;
  22. }
  23. }
  24. if (AnyEvent_)
  25. did_->HaveEventIterated_var=true;
  26. if ( initializationPhase_ || (( (Init_ && nrel_ > 0) || AnyEvent_) && (FirstEvent || EventIterate_) && Iter <= MaxIter)) {
  27. if (GlobalError_ != 0) goto leave;
  28. if (PrintEvent&(1<<1)) {
  29. if (DymolaOneIteration_==0 || DymolaOneIteration_==4)
  30. DymosimMessage("Iterating to find consistent restart conditions.");
  31. } else if (Iter==MaxIter) {
  32. if (!(PrintEvent&(1<<10))) {
  33. DymosimMessage("");
  34. DymosimMessage("On the final iteration for restart conditions we get:");
  35. PrintEvent|=(1<<1);
  36. }
  37. }
  38. if (initializationPhase_==1)
  39. initializationPhase_=2;
  40. else {
  41. Init_ = false;
  42. initializationPhase_=0;
  43. }
  44. NewParameters_ = NewParameters_ && AnyEventParameter_;
  45. DYNEvent = true;
  46. *icall_ = 0;
  47. if (DymolaOneIteration_==4) {
  48. DymolaOneIteration_=0;
  49. } else if (DymolaOneIteration_) {
  50. DymolaOneIteration_=3;
  51. goto leave;
  52. }
  53. goto iterate;
  54. } else if (Iter > MaxIter) {
  55. DymosimMessage("");
  56. DymosimMessageDouble("ERROR: Finding consistent restart conditions failed at time: ", DYNTime);
  57. DymosimMessage("");
  58. *QiErr = 1;
  59. GlobalError_ = 1;
  60. goto leave;
  61. }
  62. if(DymolaOneIteration_!=0){
  63. int i;
  64. for(i=0;i<NWhen_;++i){QEvaluate_[i]=QEvaluateNew_[i];};
  65. }
  66. DymolaOneIteration_=0;
  67. Init_ = FirstEvent; /* restore Init */
  68. FirstEvent = false;
  69. {
  70. if (( (Init_ && nrel_ > 0) || AnyEvent_ || Iter > 1) && (PrintEvent&(1<<1))) {
  71. DymosimMessageDouble(" during event at Time : ", DYNTime);
  72. }
  73. }
  74. #ifdef DYNEventSpecial
  75. if (*QiErr==0 && !Init_ && DYNEvent && !AnyDEvent_ && !AnyREvent_) {
  76. if (AnyIEvent_) {
  77. *QiErr=-994;
  78. } else {
  79. *QiErr=-995;
  80. }
  81. }
  82. #endif
  83. if ( Init_ ) delayiniclos();
  84. if (DYNFindEvent) CheckForEvents(did_,DYNTime, Init_, DYNEvent, QZ_, nrel2_, F_, (DYNFindEvent==1)?(nx_):(0), duser_, iuser_);
  85. #if 0
  86. UpdateDaeF_(DYNEvent, F_, XD_);
  87. #endif
  88. /* Modify only enabled crossing functions. */
  89. if (SpuriousEvents_ && *idemand_ == 4) {
  90. int i1_;
  91. for (i1_ = 1; i1_ <= nrel_; i1_++) {
  92. if (FirstCross_ || Qenable_[i1_]) {
  93. QZold_[2*i1_-2] = QZ_[2*i1_-2];
  94. QZold_[2*i1_-1] = QZ_[2*i1_-1];
  95. } else {
  96. QZ_[2*i1_-2] = QZold_[2*i1_-2];
  97. QZ_[2*i1_-1] = QZold_[2*i1_-1];
  98. }
  99. }
  100. FirstCross_ = 0;
  101. } else if (!SpuriousEvents_ && DYNEvent) {
  102. int i1_;
  103. for (i1_ = 1; i1_ <= nrel_; i1_++)
  104. if (!Qenable_[i1_]) {
  105. if (QL_[i1_]&2 || QZ_[2*i1_-1]==0) {
  106. QZ_[2*i1_-2]=QZ_[2*i1_-1]=0.1;
  107. }
  108. QL_[i1_]&=1;
  109. } else {
  110. QL_[i1_]&=3;
  111. }
  112. if (did_->DymolaEventOptional_var) for(i1_=0;i1_<2*nrel_;i1_++) {QZold_[i1_]=QZ_[i1_];}
  113. }
  114. } else { /* return jump from setjmp/longjmp */
  115. *QiErr = 1L;
  116. #ifdef AutoResetAfter
  117. if (*QiErr!=0 && *QiErr!=-999 && *QiErr!=-998) {
  118. resetActive=1;
  119. restartTime=DYNTime+AutoResetAfter;
  120. *QiErr=GlobalError_=0;
  121. }
  122. #endif
  123. return 0;
  124. }
  125. #if defined(Sections_)
  126. *icall_ = *idemand_;
  127. #else
  128. *icall_ = 4;
  129. #endif
  130. leave:
  131. #if !defined(DYMOLA_DSPACE) && !defined(NO_FILE) && defined(DymolaPrecisionTiming_) && defined(DymosimRealTimePriority_)
  132. if (*idemand_==7) {
  133. int i,maxi=0;
  134. for(i=0;;++i) {
  135. if (i*2>=did_->DymolaTimeZeroLength_var || did_->DymolaTimeZero_vec[2*i+1]==0)
  136. break;
  137. }
  138. maxi=i;
  139. if (maxi>0) {
  140. FILE*f=fopen("plotTiming.mos","w");
  141. fprintf(f,"times=fill(0.1,%d,2);\n",maxi);
  142. for(i=0;i<maxi;++i) {
  143. fprintf(f,"times[%d,:]={%g,%g};\n",i+1,did_->DymolaTimeZero_vec[2*i],did_->DymolaTimeZero_vec[2*i+1]);
  144. }
  145. fclose(f);
  146. DymosimMessage("RunScript(\"plotTiming.mos\",true);plotArray(times[:,1],times[:,2],-1);");
  147. }
  148. }
  149. #endif
  150. #if defined(GenerateSimulinkTiming) && defined(DynSimStruct) && !defined(DYMOLA_DSPACE)
  151. if (*idemand_==7) {
  152. DymosimMessageDouble("Time for solution:",CurrentClockTime-did_->TimeStartOfSimulation_var);
  153. }
  154. #endif
  155. if (GlobalError_ != 0 && *QiErr==0)
  156. *QiErr = GlobalError_;
  157. #ifdef AutoResetAfter
  158. if (*QiErr!=0 && *QiErr!=-999 && *QiErr!=-998) {
  159. resetActive=1;
  160. restartTime=DYNTime+AutoResetAfter;
  161. *QiErr=GlobalError_=0;
  162. }
  163. #endif
  164. return 0;
  165. }
  166. static struct DYNInstanceData tempData={0,0, 0,0,
  167. #ifdef DynSimStruct
  168. 1
  169. #else
  170. 0
  171. #endif
  172. ,{0.0},{0},0.0,
  173. 0.0,1e30,0.0,0.0,1.0,1.0,-1e30,
  174. 0,
  175. #ifdef DymolaInitializeStateFirst_
  176. 1
  177. #else
  178. 0
  179. #endif
  180. ,0,0,0.0,0,0,0,0, 0,0,0,
  181. 1.0, 0.0, 0.1, 0, 0, 0.0, 0.0,
  182. -1e33,-1e33,{{0}},
  183. #ifdef NrDymolaTimers_
  184. NrDymolaTimers_
  185. #else
  186. 1
  187. #endif
  188. ,{0},{0},
  189. #ifdef DymolaNrStepTimers
  190. DymolaNrStepTimers
  191. #else
  192. 0
  193. #endif
  194. ,0,{0},{0}, {0},{0},{0},{0},{0},{0},{0},{0}};
  195. DYMOLA_STATIC void DYNInitializeDid(struct DYNInstanceData*did_) {
  196. if (did_) {
  197. #if defined(DYN_MULTINSTANCE)
  198. struct DYN_ThreadData*threadData=DYN_GetThreadData();
  199. if (threadData) {threadData->m_external=0;threadData->did=0;}
  200. #endif
  201. *did_=tempData;
  202. }
  203. }
  204. DYMOLA_STATIC void registerTimeEvent(const double atTime) {
  205. registerTimeEventNew(atTime, &tempData);
  206. }
  207. DYMOLA_STATIC void registerTimeEventNew(const double atTime,struct DYNInstanceData*did_) {
  208. struct BasicDDymosimStruct*basicD=getBasicDDymosimStructNew(did_);
  209. double eventAccuracy;
  210. eventAccuracy=(6*DBL_EPSILON)*(fabs(atTime)+basicD->mOrigTimeError);
  211. #if 0
  212. /* Simple case, just move up end-point a little */
  213. NextTimeEvent=Dymola_min(atTime+eventAccuracy,NextTimeEvent);
  214. /*DymosimMessageDouble("Next Event:",NextTimeEvent);*/
  215. #else
  216. /* The logic is as follows: */
  217. /* All time events within TimeEventAccuracy will trigger one event.*/
  218. /* This event will occur after all of the events has occured.*/
  219. /* The next interval with events is [startNextTimeEvent,NextTimeEvent].*/
  220. /* The maximum length is eventAccuracy */
  221. if (basicD->mNextTimeEvent>=1e30)
  222. did_->startNextTimeEvent_var=basicD->mNextTimeEvent;
  223. /* Initialization. Should be moved */
  224. /*DymosimMessageDouble("Register ",atTime);*/
  225. if (atTime>=basicD->mNextTimeEvent+eventAccuracy)
  226. return; /* Event in the far future, ignore */
  227. else if (atTime<did_->startNextTimeEvent_var) {
  228. /* First event in the interval */
  229. did_->startNextTimeEvent_var=atTime;
  230. if (did_->startNextTimeEvent_var+eventAccuracy<basicD->mNextTimeEvent) {
  231. /* Switch to a new interval: [atTime,atTime] */
  232. basicD->mNextTimeEvent=atTime;
  233. }
  234. } else if ((atTime<=did_->startNextTimeEvent_var+eventAccuracy)&&(atTime>basicD->mNextTimeEvent)) {
  235. /* Last event in the interval */
  236. basicD->mNextTimeEvent=atTime;
  237. };
  238. /*DymosimMessageDouble("Next time event",NextTimeEvent);*/
  239. #endif
  240. }
  241. static double DymosimGetTime2() {
  242. #if defined(DYN_MULTINSTANCE)
  243. if (DYN_GetThreadData()->did) {
  244. return DYN_GetThreadData()->did->time_var;
  245. }
  246. #endif
  247. return tempData.time_var;
  248. };
  249. DYMOLA_STATIC int isModelicaEvent(void) {
  250. #if defined(DYN_MULTINSTANCE)
  251. if (DYN_GetThreadData()->did) {
  252. return DYN_GetThreadData()->did->Event_var;
  253. }
  254. #endif
  255. return tempData.Event_var;
  256. }
  257. DYMOLA_STATIC struct ExternalTable_* DymosimGetExternalObject() {
  258. #if defined(DYN_MULTINSTANCE)
  259. if (DYN_GetThreadData()->did) {
  260. return DYN_GetThreadData()->did->externalTable_vec;
  261. }
  262. #endif
  263. return tempData.externalTable_vec;
  264. };
  265. DYMOLA_STATIC double initialTime(void) {
  266. #if defined(DYN_MULTINSTANCE)
  267. if (DYN_GetThreadData()->did) {
  268. return DYN_GetThreadData()->did->InitTime_var;
  269. }
  270. #endif
  271. return tempData.InitTime_var;
  272. }
  273. DYMOLA_STATIC int GetDymolaOneIteration(struct DYNInstanceData*did_) {
  274. if (did_) return did_->DymolaOneIteration_var;
  275. return tempData.DymolaOneIteration_var;
  276. }
  277. DYMOLA_STATIC void SetDymolaOneIteration(struct DYNInstanceData*did_, int val) {
  278. if (did_) did_->DymolaOneIteration_var=val;
  279. else tempData.DymolaOneIteration_var=val;
  280. }
  281. DYMOLA_STATIC void SetDymolaEventOptional(struct DYNInstanceData*did_, int val) {
  282. if (did_) did_->DymolaEventOptional_var=val;
  283. else tempData.DymolaEventOptional_var=val;
  284. }
  285. DYMOLA_STATIC int GetDymolaHaveEventIterated(struct DYNInstanceData*did_) {
  286. if (did_) return did_->HaveEventIterated_var;
  287. else return tempData.HaveEventIterated_var;
  288. }
  289. DYMOLA_STATIC void SetDymolaJacobianPointers2(struct DYNInstanceData*did_, double * QJacobian_,double * QBJacobian_,double * QCJacobian_,double * QDJacobian_,int QJacobianN_,
  290. int QJacobianNU_,int QJacobianNY_,double * QJacobianSparse_,int * QJacobianSparseR_,int * QJacobianSparseC_,int QJacobianNZ_,int *QJacobianABCDNZ_) {
  291. if (!did_) did_=&tempData;
  292. did_->QJacobian_var=QJacobian_;
  293. did_->QBJacobian_var=QBJacobian_;
  294. did_->QCJacobian_var=QCJacobian_;
  295. did_->QDJacobian_var=QDJacobian_;
  296. did_->QJacobianN_var=QJacobianN_;
  297. did_->QJacobianNU_var=QJacobianNU_;
  298. did_->QJacobianNY_var=QJacobianNY_;
  299. did_->QJacobianSparse_var=QJacobianSparse_;
  300. did_->QJacobianSparseR_var=QJacobianSparseR_;
  301. did_->QJacobianSparseC_var=QJacobianSparseC_;
  302. did_->QJacobianNZ_var=QJacobianNZ_;
  303. did_->QSparseABCD_var=QJacobianABCDNZ_!=0;
  304. if (QJacobianABCDNZ_) *QJacobianABCDNZ_=
  305. #ifdef AnalyticJacobianElementsABCD_
  306. AnalyticJacobianElementsABCD_
  307. #else
  308. 0
  309. #endif
  310. ;
  311. }
  312. DYMOLA_STATIC void SetDymolaJacobianPointers(struct DYNInstanceData*did_, double * QJacobian_,double * QBJacobian_,double * QCJacobian_,double * QDJacobian_,int QJacobianN_,
  313. int QJacobianNU_,int QJacobianNY_,double * QJacobianSparse_,int * QJacobianSparseR_,int * QJacobianSparseC_,int QJacobianNZ_) {
  314. SetDymolaJacobianPointers2(did_, QJacobian_, QBJacobian_, QCJacobian_, QDJacobian_, QJacobianN_, QJacobianNU_, QJacobianNY_, QJacobianSparse_, QJacobianSparseR_, QJacobianSparseC_, QJacobianNZ_, 0);
  315. };
  316. DYMOLA_STATIC struct DymolaTimes* GetDymolaTimers(struct DYNInstanceData*did_, int*len) {
  317. if (!did_) did_=&tempData;
  318. if (len) *len=did_->DymolaTimerStructsLen_var;
  319. return did_->DymolaTimerStructs_vec;
  320. }
  321. DYMOLA_STATIC int* GlobalErrorPointer(void) {
  322. #if defined(DYN_MULTINSTANCE)
  323. if (DYN_GetThreadData()->did) {
  324. return &(DYN_GetThreadData()->did->GlobalError_var);
  325. }
  326. #endif
  327. return &(tempData.GlobalError_var);
  328. }
  329. DYMOLA_STATIC int dsblock_(int *idemand_, int *icall_,
  330. double *time, double X_[], double XD_[], double U_[],
  331. double DP_[], int IP_[], Dymola_bool LP_[],
  332. double F_[], double Y_[], double W_[], double QZ_[],
  333. double duser_[], int iuser_[], void* cuser_[],
  334. int *QiErr)
  335. {
  336. return dsblock_tid(idemand_, icall_, time, X_, XD_, U_, DP_, IP_, LP_, F_, Y_, W_, QZ_, duser_, iuser_, cuser_, &tempData, QiErr, 0);
  337. }
  338. struct DeclarePhase;
  339. DYMOLA_STATIC void declareNew_(double x0_[], double dp_[], double du_[], void*cuser_[], int *QiErr, int setDefault_, struct DeclarePhase*);
  340. DYMOLA_STATIC void declare_(double x0_[], double dp_[], double du_[], void*cuser_[], int *QiErr)
  341. {
  342. /* End dsblock4.c */
  343. declareNew_(x0_, dp_, du_, cuser_, QiErr, 0, 0);
  344. }
  345. DYMOLA_STATIC void declareNew_(double x0_[], double dp_[], double du_[], void*cuser_[], int *QiErr, int setDefault_, struct DeclarePhase*phase)
  346. {
  347. int setDefaultX_=0,setDefaultU_=0,setDefaultY_=0,setDefaultP_=0,setDefaultDX_=0,setDefaultW_=0;