dsblock1.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. /* Begin dsblock1.c */
  2. /*
  3. * Copyright (C) 1997-2001 Dynasim AB.
  4. * All rights reserved.
  5. *
  6. */
  7. /* Start of DSblock C output.
  8. Version: 1.8, 1997-04-29
  9. 1.9, 1997-07-04 relative tolerance of integrator used
  10. for nonlinear equation solvers
  11. 1.10, 1997-11-28 - stdlib.h included in order to get no conflicts
  12. with a possible f2c.h in userfunc.c
  13. - longjmp introduced for error messages, in order
  14. that the model evaluation is stopped immediately
  15. - event iteration at initial time even if
  16. EventIterate_ = 0
  17. - userfunc.c before RootFinder_/EventIterate_ flags
  18. in order that these flags can be also set in
  19. userfunc.c (often more convenient).
  20. 1.11, 1998-03-22 - changes for linear solvers (and tearing)
  21. 1.12, 1999-01-25 - explicit initializer for matrices to avoid
  22. initialization at runtime (increases executable size)
  23. 1.13, 1999-03-03 - includes userdefs.h (userfunc.c was split in two)
  24. */
  25. #if !defined(DSE_STRUCT)
  26. #if defined(DS_EMBEDDED)
  27. #define DSE_STRUCT sts->
  28. #else
  29. #define DSE_STRUCT
  30. #endif
  31. #endif
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include <math.h>
  35. #include <setjmp.h>
  36. #include <dsblock.h>
  37. #include <userdefs.h>
  38. #include <userfunc.c> /* To include user defined functions called
  39. from model equations. */
  40. #if defined(UNIX) && defined(__GNUC__) && defined(FMI_MODULE_NAME)
  41. /* need access to non-standard function dladdr */
  42. #define __USE_GNU
  43. #include <dlfcn.h>
  44. #undef __USE_GNU
  45. #endif /* defined(UNIX) ... */
  46. #if defined(RT) || defined(NRT) || defined(DYMOLA_DSPACE)
  47. #if !defined(LABCAR)
  48. #define NO_FILE_SYSTEM 1
  49. #define NO_PID 1
  50. #define NO_TIME 1
  51. #endif
  52. #endif
  53. #define MODELICA_EXTERNAL static
  54. #include <ModelicaInternal.c> /* Utility functions in Modelica 2.1 */
  55. #include <ModelicaStrings.c>
  56. #if ! defined(RootFinder_)
  57. # if ! defined(DynSimStruct) || defined(Matlab51) || defined(FMU_SOURCE_CODE_EXPORT)
  58. # define RootFinder_ 1 /* Root finder available in integration algorithm. */
  59. # else
  60. # define RootFinder_ 0
  61. # endif
  62. #endif
  63. #if ! defined(EventIterate_)
  64. # define EventIterate_ 1 /* 1: Iterate for consistent conditions after event.
  65. 0: Propagate event next time. */
  66. #endif
  67. #if ! defined(TryLUFactorization_)
  68. #define TryLUFactorization_ 0 /* 0: Do not attempt LU-factorization (i.e. use QR-factorization)*/
  69. #endif
  70. #if ! defined(EquilibMatrix_)
  71. #define EquilibMatrix_ 1 /* Row and column equilibrate matrix: Improves reliability at some cost */
  72. #endif
  73. #if ! defined(LargeEPS_)
  74. #define LargeEPS_ 1e-4 /* An upper bound for the event epsilon */
  75. #endif
  76. #if ! defined(SlowIter_)
  77. #define SlowIter_ 5 /* Number of iterations before attempting to increase event epsilon */
  78. #endif
  79. #if ! defined(SpuriousEvents_)
  80. # define SpuriousEvents_ 0
  81. #endif
  82. #if ! defined(DAEsolver_)
  83. # define DAEsolver_ 0
  84. #endif
  85. #if !defined(DymolaAimForHighAccuracy_)
  86. #define DymolaAimForHighAccuracy_ 1
  87. #endif
  88. #if !defined(DymolaNewJacobian_)
  89. #define DymolaNewJacobian_ 1
  90. #endif
  91. #if !defined(DymolaAllowNewJacobianAnyway_)
  92. #define DymolaAllowNewJacobianAnyway_ 1
  93. #endif
  94. #if !defined(DymolaNrStepTimers)
  95. #define DymolaNrStepTimers 100000
  96. #endif
  97. #if !defined(DymolaNonLinearIterations_)
  98. #define DymolaNonLinearIterations_ 0
  99. #elif DymolaNonLinearIterations_>8
  100. #error Cannot set DymolaNonLinearIterations_ above 8
  101. #undef DymolaNonLinearIterations_
  102. #define DymolaNonLinearIterations_ 8
  103. #endif
  104. #if 0 && DymolaPrecisionTiming_ && !defined(DymolaUninterruptedTimers_)
  105. #define DymolaUninterruptedTimers_ 1
  106. #endif
  107. #if DymolaPrecisionTiming_ && !defined(DymolaUseRDTSC_)
  108. #define DymolaUseRDTSC_ 1
  109. #endif
  110. #include <dsutil.h>
  111. #if !defined(DYMOLA_DSPACE) && !defined(RT)
  112. void DymolaOnInterrupt(void) {
  113. #if DymolaUninterruptedTimers_ && defined(_MSC_VER) && defined(_M_IX86)
  114. __asm {
  115. sti
  116. }
  117. #elif DymolaUninterruptedTimers_ && defined(__GNUC__) && defined(i386)
  118. __asm__("sti");
  119. #endif
  120. }
  121. int DymolaNoInterrupt(void) {
  122. #if DymolaUninterruptedTimers_ && defined(_MSC_VER) && defined(_M_IX86)
  123. __asm {
  124. cli
  125. }
  126. #elif DymolaUninterruptedTimers_ && defined(__GNUC__) && defined(i386)
  127. __asm__("cli");
  128. #endif
  129. return 0;
  130. }
  131. #endif
  132. DYMOLA_STATIC void GetDimensions2(int *nx_, int *nx2_, int *nu_, int *ny_, int *nw_,
  133. int *np_, int*nsp, int *nrel2_, int *nrel_, int *ncons_, int *dae_);
  134. DYMOLA_STATIC void UpdateDaeF_(Dymola_bool Init, double F_[], double XD_[]);
  135. #define MAXQ 10000 /* Maximum number of sub-expressions. */
  136. #define MaxMat 100 /* Maximum size of linear systems of equations. */
  137. /* QMaxNonLin >= MaxMat required */
  138. #define MAXEVENT 2000 /* Maximum number of event relations. */
  139. #define QMaxNonLin 100 /* Maximum size of non-linear systems of equations. */
  140. /* QMaxNonLin >= MaxMat required, because DymLin uses */
  141. /* QSol_, QRes_, QJac_ from the nonlinear equation and the */
  142. /* work arrays dwork_, iwork_ from the linear equation storage */
  143. #if defined(DYMOLA_DSPACE) && defined(__GNUC__)
  144. #define ZERO_INITIALIZED = {0}
  145. #else
  146. #define ZERO_INITIALIZED /* = {0} */
  147. #endif
  148. /* Not used anymore: */
  149. static double d1_;
  150. static int c1_, c2_, c3_;
  151. #define DymolaStoreAuxiliaries_ (((struct BasicIDymosimStruct*)(DSE_STRUCT iuser_))->mDymolaStoreAuxiliaries)
  152. /* Auxiliary variables. */
  153. static double Q_[MAXQ] ZERO_INITIALIZED;
  154. static int DYNStrInit(struct DYNInstanceData*);
  155. DYMOLA_STATIC void DYNSetAuxString(struct DYNInstanceData*did_,const char*,int i);
  156. DYMOLA_STATIC void DYNSetAuxStringArray(struct DYNInstanceData*did_,struct StringArray,int i);
  157. DYMOLA_STATIC const char*DYNGetAuxStr(struct DYNInstanceData*did_,int i);
  158. /* Variables to handle linear systems of equations. */
  159. static double qa_[MaxMat*MaxMat] ZERO_INITIALIZED, qb_[MaxMat] ZERO_INITIALIZED;
  160. static double dwork_[MaxMat*MaxMat+5*MaxMat] ZERO_INITIALIZED;
  161. static int iwork_[3*MaxMat];
  162. /* Variables to handle non-linear systems of equations. */
  163. #define QI_ (20+(QMaxNonLin*QMaxNonLin+15*QMaxNonLin)/2)
  164. static double QRes_[QMaxNonLin];
  165. static double QSol_[QMaxNonLin];
  166. static double QJac_[QMaxNonLin*QMaxNonLin] ZERO_INITIALIZED;
  167. static double QD_[QI_] ZERO_INITIALIZED;
  168. static int QIDUM_[20];
  169. static double Qtol;
  170. static int QInfRev, QiOpt, QNnl, Qinfo, QNLnr, QBase;
  171. DYMOLA_STATIC int* QNLfunc;
  172. DYMOLA_STATIC int* QNLjac;
  173. DYMOLA_STATIC int QNLmax;
  174. #define PrintEvent (((struct BasicIDymosimStruct*) (DSE_STRUCT iuser_))->mPrintEvent)
  175. #define inJacobian_ (((struct BasicIDymosimStruct*) (DSE_STRUCT iuser_))->mInJacobian)
  176. #define solverHandleEq_ (((struct BasicIDymosimStruct*) (DSE_STRUCT iuser_))->mSolverHandleEq)
  177. #define continueSimulate_ (((struct BasicIDymosimStruct*) (DSE_STRUCT iuser_))->mContinueSimulate)
  178. #define dymolaParametersNr_ (((struct BasicIDymosimStruct*) (DSE_STRUCT iuser_))->mParametersNr)
  179. static int nx_, nx2_, nu_, ny_, nw_, np_, nsp_, nrel2_, nrel_, ncons_, dae_;
  180. #define DYNTime (did_->time_var)
  181. #define InitTime (did_->InitTime_var)
  182. #define LastTime (did_->LastTime_var)
  183. #define StepSize (did_->StepSize_var)
  184. #define currentStepSize_ (did_->currentStepSize_var)
  185. #define currentStepSizeRatio_ (did_->currentStepSizeRatio_var)
  186. #define previousTime_ (did_->previousTime_var)
  187. #define DYNhelp (did_->helpvar_vec)
  188. #define DYNEvent (did_->Event_var)
  189. #define initializationPhase_ (did_->initializationPhase_var)
  190. #define Iter (did_->Iter_var)
  191. #define MaxIter (did_->MaxIter_var)
  192. #define EPS_ (did_->EPS_var)
  193. #define FirstCross_ (did_->FirstCross_var)
  194. #define FirstEvent (did_->FirstEvent_var)
  195. #define ResetCounter_ (did_->ResetCounter_var)
  196. #define DYNHReject (did_->HReject_var)
  197. #define GlobalError_ (did_->GlobalError_var)
  198. #define MixedFailFlag_ (did_->MixedFailFlag_var)
  199. #define PerformIteration_ (did_->PerformIteration_var)
  200. #define DymolaHomotopyLambda (did_->DymolaHomotopyLambda_var)
  201. #define DymolaHomotopyLambdaFail (did_->DymolaHomotopyLambdaFail_var)
  202. #define DymolaHomotopyLambdaDelta (did_->DymolaHomotopyLambdaDelta_var)
  203. #define DymolaHomotopyUsed (did_->DymolaHomotopyUsed_var)
  204. #define DymolaUserHomotopy (did_->DymolaUserHomotopy_var)
  205. #define DymolaOneIteration_ (did_->DymolaOneIteration_var)
  206. #define EqRemember1Time_ (did_->EqRemember1Time_var)
  207. #define EqRemember2Time_ (did_->EqRemember2Time_var)
  208. #define QPre_ (did_->QPre_vec)
  209. #define RefPre_ (did_->RefPre_vec)
  210. #define EqRemember1_ (did_->EqRemember1_vec)
  211. #define EqRemember2_ (did_->EqRemember2_vec)
  212. #define DYNAuxStr_ (did_->DYNAuxStrPtr_vec)
  213. #define Aux_ (did_->Aux_vec)
  214. #define QEvaluate_ (did_->QEvaluate_vec)
  215. #define QEvaluateNew_ (did_->QEvaluateNew_vec)
  216. #define QCheckIf_ (did_->QCheckIf_vec)
  217. #define QTimed_ (did_->QTimed_vec)
  218. #define Qenable_ (did_->Qenable_vec)
  219. #define NextSampleTime_ (did_->NextSampleTime_vec)
  220. #define NextSampleTimeNew_ (did_->NextSampleTimeNew_vec)
  221. #define NextSampleAct_ (did_->NextSampleAct_vec)
  222. #define NextSampleActNew_ (did_->NextSampleActNew_vec)
  223. #define QL_ (did_->QL_vec)
  224. #define QRel_ (did_->QRel_vec)
  225. #define QM_ (did_->QM_vec)
  226. #define Qn_ (did_->Qn_vec)
  227. #define Qp_ (did_->Qp_vec)
  228. #define Qscaled_ (did_->Qscaled_vec)
  229. #define QZold_ (did_->QZold_vec)
  230. #define oldQZ_ (did_->oldQZ_vec)
  231. #define oldQZDummy_ (did_->oldQZDummy_vec)
  232. #define oldQZ2_ (did_->oldQZ2_vec)
  233. #define oldQZ3_ (did_->oldQZ3_vec)
  234. #define QImd_ (did_->QImd_vec)
  235. #define QIml_ (did_->QIml_vec)
  236. #define Init_ (did_->Init_var)
  237. #define AnyEvent_ (did_->AnyEvent_var)
  238. #define AnyDEvent_ (did_->AnyDEvent_var)
  239. #define AnyREvent_ (did_->AnyREvent_var)
  240. #define AnyIEvent_ (did_->AnyIEvent_var)
  241. #define AnyEventParameter_ (did_->AnyEventParameter_var)
  242. #define NewParameters_ (did_->NewParameters_var)
  243. #define dymolaEventsNr_ (did_->dymolaEventsNr_var)
  244. #ifndef DYMOLA_TIMES
  245. #define DYMOLA_TIMES
  246. struct DymolaTimes {
  247. int num;
  248. double maxim;
  249. double minim;
  250. double total;
  251. int numAccum;
  252. double maximAccum;
  253. double minimAccum;
  254. double totalAccum;
  255. const char*name;
  256. };
  257. #endif
  258. #if !defined(NCheckIf_)
  259. #define NCheckIf_ 0
  260. #endif
  261. #if !defined(NGlobalHelp_)
  262. #define NGlobalHelp_ 100
  263. #endif
  264. #if !defined(NGlobalHelpI_)
  265. #define NGlobalHelpI_ 100
  266. #endif
  267. typedef struct DYNInstanceData {
  268. struct BasicDDymosimStruct*basicD;
  269. struct BasicIDymosimStruct*basicI;
  270. int DymolaOneIteration_var; /* =2 first, =3 subsequent, 4 subsequent no iter, 5 subsequent without iteration, return !=0 => need more */
  271. int HaveEventIterated_var;
  272. int DymolaEventOptional_var;
  273. double helpvar_vec[NGlobalHelp_+1];
  274. int helpvari_vec[NGlobalHelpI_+1];
  275. double time_var;
  276. double InitTime_var;
  277. double LastTime_var;
  278. double StepSize_var;
  279. double currentStepSize_var;
  280. double currentStepSizeRatio_var;
  281. double currentStepSizeRatio2_var; /* Unused */
  282. double previousTime_var;
  283. Dymola_bool Event_var;
  284. int initializationPhase_var;
  285. int Iter_var, MaxIter_var;
  286. double EPS_var;
  287. int FirstCross_var;
  288. Dymola_bool FirstEvent_var;
  289. int ResetCounter_var;
  290. int HReject_var;
  291. int GlobalError_var;
  292. int MixedFailFlag_var;
  293. Dymola_bool PerformIteration_var;
  294. double DymolaHomotopyLambda_var;
  295. double DymolaHomotopyLambdaFail_var;
  296. double DymolaHomotopyLambdaDelta_var;
  297. int DymolaHomotopyUsed_var;
  298. int DymolaUserHomotopy_var;
  299. double TimeStartOfSimulation_var;
  300. double startNextTimeEvent_var;
  301. double EqRemember1Time_var;
  302. double EqRemember2Time_var;
  303. struct DymolaTimes DymolaTimerStructs_vec[
  304. #ifdef NrDymolaTimers_
  305. NrDymolaTimers_ ? NrDymolaTimers_ : 1
  306. #else
  307. 1
  308. #endif
  309. ];
  310. int DymolaTimerStructsLen_var;
  311. double DymolaStartTimers_vec[
  312. #ifdef NrDymolaTimers_
  313. NrDymolaTimers_ ? NrDymolaTimers_ : 1
  314. #else
  315. 1
  316. #endif
  317. ];
  318. double DymolaTimeZero_vec[DymolaNrStepTimers];
  319. int DymolaTimeZeroLength_var;
  320. int DymolaTimecounter_var;
  321. double QPre_vec[SizePre_?SizePre_:1];
  322. double RefPre_vec[SizePre_?SizePre_:1];
  323. double EqRemember1_vec[SizeEq_?SizeEq_:1];
  324. double EqRemember2_vec[SizeEq_?SizeEq_:1];
  325. double Aux_vec[MAXAux+10000];
  326. Dymola_bool QEvaluate_vec[NWhen_+1];
  327. Dymola_bool QEvaluateNew_vec[NWhen_+1];
  328. double QCheckIf_vec[NCheckIf_+1];
  329. Dymola_bool QTimed_vec[NTim_+1];
  330. Dymola_bool Qenable_vec[NRel_+1];
  331. int oldReset_var;
  332. double NextSampleTime_vec[NSamp_+1];
  333. double NextSampleTimeNew_vec[NSamp_+1];
  334. Dymola_bool NextSampleAct_vec[NSamp_+1];
  335. Dymola_bool NextSampleActNew_vec[NSamp_+1];
  336. Dymola_bool QL_vec[NRel_+1];
  337. double QRel_vec[NRel_+1];
  338. double QM_vec[NRel_+1];
  339. double Qn_vec[NRel_+1];
  340. double Qp_vec[NRel_+1];
  341. double Qscaled_vec[NRel_+1];
  342. double QZold_vec[2*NRel_+1];
  343. double oldQZ_vec[2*NRel_+1];
  344. double oldQZDummy_vec[2*NRel_+1];
  345. double oldQZ2_vec[2*NRel_+1];
  346. double oldQZ3_vec[2*NRel_+1];
  347. Dymola_bool Init_var, AnyEvent_var, AnyDEvent_var, AnyREvent_var, AnyIEvent_var, AnyEventParameter_var, NewParameters_var;
  348. struct ExternalTable_ externalTable_vec[
  349. #ifdef NExternalObject_
  350. NExternalObject_+1
  351. #else
  352. 1
  353. #endif
  354. ];
  355. int dymolaParametersNrOld_;
  356. int dymolaEventsNr_var;
  357. double * QJacobian_var;
  358. double * QBJacobian_var;
  359. double * QCJacobian_var;
  360. double * QDJacobian_var;
  361. int QJacobianN_var;
  362. int QJacobianNU_var;
  363. int QJacobianNY_var;
  364. double * QJacobianSparse_var;
  365. int* QJacobianSparseR_var ;
  366. int* QJacobianSparseC_var ;
  367. int QJacobianNZ_var;
  368. int QSparseABCD_var;
  369. double QImd_vec[
  370. #ifdef NI_
  371. NI_*(2*NI_+5)+NX_*(4+3*NI_)+
  372. #endif
  373. 1
  374. ];
  375. int QIml_vec[
  376. #ifdef NI_
  377. 5*NI_+
  378. #endif
  379. 1
  380. ];
  381. char DYNAuxStrBuff_vec[
  382. #if defined(MAXAuxStr_) && MAXAuxStr_>0
  383. MAXAuxStr_
  384. #else
  385. 1
  386. #endif
  387. *
  388. #if defined(MAXAuxStrLen_) && MAXAuxStrLen_>10
  389. MAXAuxStrLen_
  390. #else
  391. 10
  392. #endif
  393. ];
  394. char* DYNAuxStrPtr_vec[
  395. #if defined(MAXAuxStr_) && MAXAuxStr_>0
  396. MAXAuxStr_
  397. #else
  398. 1
  399. #endif
  400. ];
  401. } DYNInstanceData;
  402. /* Temporary ones: */
  403. static Dymola_bool sectioncondition = true;
  404. DYMOLA_STATIC int isModelicaEvent(void);
  405. DYMOLA_STATIC int* GlobalErrorPointer(void);
  406. struct BasicDDymosimStruct*getBasicDDymosimStructNew(struct DYNInstanceData*did) {
  407. if (did && did->basicD) return did->basicD;
  408. return getBasicDDymosimStruct();
  409. }
  410. #define triggerStepEvent_ (((struct BasicIDymosimStruct*) (DSE_STRUCT iuser_))->mTriggerStepEvent)
  411. #ifndef FindEvent_
  412. #define DYNFindEvent (((struct BasicIDymosimStruct*) (DSE_STRUCT iuser_))->mFindEvent)
  413. #else
  414. #define DYNFindEvent FindEvent_
  415. #if 0
  416. #undef FindEvent_
  417. #define FindEvent_ 1
  418. #endif
  419. #endif
  420. #define DYMResourceQuote2(fmin) #fmin
  421. #define DYMResourceQuote(fmin) DYMResourceQuote2(fmin)
  422. #if defined(DYN_MULTINSTANCE)
  423. DYMOLA_STATIC size_t dyn_allowMultipleInstances=sizeof(struct DYNInstanceData);
  424. #else
  425. DYMOLA_STATIC size_t dyn_allowMultipleInstances=0;
  426. #endif
  427. #if defined(_WIN32) && (defined(_MSC_VER) || defined(DYN_MULTINSTANCE)) || defined(__MINGW32__)
  428. #include <windows.h>
  429. #if defined(DYN_MULTINSTANCE)
  430. static DWORD dsTlsDynInstance=0;
  431. #endif
  432. #if !defined(FMU_SOURCE_CODE_EXPORT) && defined(FMI_MODULE_NAME)
  433. #if defined(DYN_MULTINSTANCE)
  434. DYMOLA_STATIC void EnsureMarkFree(struct DYN_ThreadData*threadData);
  435. #endif
  436. BOOL __stdcall DllMain(HINSTANCE hinstDLL, /* DLL module handle*/
  437. DWORD fdwReason, /* reason called*/
  438. LPVOID lpvReserved) /* reserved*/
  439. {
  440. LPVOID lpvData;
  441. BOOL fIgnore;
  442. switch (fdwReason)
  443. {
  444. /* The DLL is loading due to process */
  445. /* initialization or a call to LoadLibrary. */
  446. case DLL_PROCESS_ATTACH:
  447. /* Allocate a TLS index.*/
  448. #if defined(DYN_MULTINSTANCE)
  449. if ((dsTlsDynInstance = TlsAlloc()) == 0xFFFFFFFF)
  450. return FALSE;
  451. #endif
  452. /* No break: Initialize the index for first thread.*/
  453. /* The attached process creates a new thread. */
  454. case DLL_THREAD_ATTACH:
  455. /* Initialize the TLS index for this thread.*/
  456. break;
  457. /* The thread of the attached process terminates.*/
  458. case DLL_THREAD_DETACH:
  459. /* Release the allocated memory for this thread.*/
  460. #if defined(DYN_MULTINSTANCE)
  461. lpvData = TlsGetValue(dsTlsDynInstance);
  462. if (lpvData != NULL) {
  463. EnsureMarkFree((struct DYN_ThreadData*)(lpvData));
  464. LocalFree((HLOCAL) lpvData);
  465. }
  466. lpvData = NULL;
  467. TlsSetValue(dsTlsDynInstance, lpvData);
  468. #endif
  469. break;
  470. /* DLL unload due to process termination or FreeLibrary. */
  471. case DLL_PROCESS_DETACH:
  472. /* Release the allocated memory for this thread. */
  473. #if defined(DYN_MULTINSTANCE)
  474. lpvData = TlsGetValue(dsTlsDynInstance);
  475. if (lpvData != NULL) {
  476. EnsureMarkFree((struct DYN_ThreadData*)(lpvData));
  477. LocalFree((HLOCAL) lpvData);
  478. }
  479. lpvData = NULL;
  480. TlsSetValue(dsTlsDynInstance, lpvData);
  481. /* Release the TLS index. */
  482. TlsFree(dsTlsDynInstance);
  483. #endif
  484. #ifndef __MINGW32__
  485. freeClocale();
  486. #endif
  487. break;
  488. default:
  489. break;
  490. }
  491. return TRUE;
  492. UNREFERENCED_PARAMETER(hinstDLL);
  493. UNREFERENCED_PARAMETER(lpvReserved);
  494. }
  495. #endif /*!defined(FMU_SOURCE_CODE_EXPORT)*/
  496. #if defined(DYN_MULTINSTANCE)
  497. static struct DYN_ThreadData* DYN_GetThreadData() {
  498. LPVOID lpvData;
  499. lpvData = TlsGetValue(dsTlsDynInstance);
  500. if (lpvData == NULL) {
  501. /* This is a critical region, but since using Tls it is already guarded */
  502. lpvData = LocalAlloc(LPTR, sizeof(struct DYN_ThreadData)); /* LPTR means fixed and zero-initialized */
  503. if (lpvData) {
  504. TlsSetValue(dsTlsDynInstance, lpvData);
  505. }
  506. }
  507. return (struct DYN_ThreadData*)(lpvData);
  508. }
  509. #endif /*defined(DYN_MULTINSTANCE)*/
  510. #endif
  511. #if defined(DYN_MULTINSTANCE) && !(defined(_WIN32))
  512. #if defined(__GNUC__) || DYN_COMPILER_SUPPORTS__THREAD
  513. static __thread struct DYN_ThreadData dyn_threadData={0};
  514. static struct DYN_ThreadData* DYN_GetThreadData() {
  515. return &dyn_threadData;
  516. }
  517. #else
  518. #error Multiple instance only supported for Windows and Gcc so far
  519. #endif
  520. #endif
  521. #if defined(RT) || defined(NRT)
  522. #if defined(DYN_MULTINSTANCE)
  523. LIBDS_API struct BasicIDymosimStruct*getBasicIDymosimStruct() {
  524. return DYN_GetThreadData()->did->basicI;
  525. }
  526. LIBDS_API struct BasicDDymosimStruct*getBasicDDymosimStruct() {
  527. return DYN_GetThreadData()->did->basicD;
  528. }
  529. LIBDS_API void setBasicStruct(double*d,int*i) {
  530. if (!DYN_GetThreadData()->did) return;
  531. DYN_GetThreadData()->did->basicI=(struct BasicIDymosimStruct*)(i);
  532. DYN_GetThreadData()->did->basicD=(struct BasicDDymosimStruct*)(d);
  533. }
  534. #else
  535. static struct BasicIDymosimStruct*basicI=0;
  536. static struct BasicDDymosimStruct*basicD=0;
  537. LIBDS_API struct BasicIDymosimStruct*getBasicIDymosimStruct() {
  538. return basicI;
  539. }
  540. LIBDS_API struct BasicDDymosimStruct*getBasicDDymosimStruct() {
  541. return basicD;
  542. }
  543. LIBDS_API void setBasicStruct(double*d,int*i) {
  544. basicI=(struct BasicIDymosimStruct*)(i);
  545. basicD=(struct BasicDDymosimStruct*)(d);
  546. }
  547. #endif
  548. #endif
  549. static const char*dymosimResourceLocation=0;
  550. #ifdef FMI_MODULE_NAME
  551. const char* dymosimFMIPath() {
  552. #if (defined(_WIN32) && defined(_MSC_VER)) || defined(__MINGW32__)
  553. static char extraPath[1000];
  554. HMODULE hMySelf=0;
  555. hMySelf=GetModuleHandleA(DYMResourceQuote(FMI_MODULE_NAME));
  556. extraPath[0] = 0;
  557. GetModuleFileNameA(hMySelf, extraPath, sizeof(extraPath)/sizeof(*extraPath));
  558. return extraPath;
  559. #else
  560. return 0;
  561. #endif
  562. }
  563. #endif
  564. DYMOLA_STATIC const char* dymosimResources(void) {
  565. static int first=1;
  566. if (first && !dymosimResourceLocation) {
  567. static char extraPath[1000];
  568. char*last;
  569. int twice=0;
  570. #if (defined(_WIN32) && defined(_MSC_VER)) || defined(__MINGW32__)
  571. HMODULE hMySelf=0;
  572. const char* separator = "\\";
  573. #ifdef FMI_MODULE_NAME
  574. hMySelf=GetModuleHandleA(DYMResourceQuote(FMI_MODULE_NAME));
  575. twice=1;
  576. #else
  577. hMySelf=GetModuleHandleA(0);
  578. #endif /* FMI_MODULE_NAME */
  579. extraPath[0] = 0;
  580. if (GetModuleFileNameA(hMySelf, extraPath, sizeof(extraPath)/sizeof(*extraPath))!=0) {
  581. #elif defined(__GNUC__)
  582. {
  583. const char* separator = "/";
  584. #if defined(UNIX) && defined(FMI_MODULE_NAME)
  585. /* Linux gcc and FMU so file */
  586. twice = 1;
  587. Dl_info dli;
  588. if (dladdr(__builtin_return_address(0), &dli) != 0 && dli.dli_fname != NULL) {
  589. strcpy(extraPath, dli.dli_fname);
  590. } else {
  591. DymosimMessage("Error: dladdr failed to fetch location of this FMU so file.");
  592. }
  593. #else /* defined(UNIX) && defined(FMI_MODULE_NAME) */
  594. /* resources for non-FMUs not supported on Linux, neglect */
  595. #endif /* defined(UNIX) && defined(FMI_MODULE_NAME) */
  596. #else /* defined(__GNUC__) ... */
  597. /* neither Windows nor gcc, neglect */
  598. {
  599. const char* separator = "/";
  600. #endif /* defined(__GNUC__) ... */
  601. extraPath[sizeof(extraPath)/sizeof(*extraPath)-1]=0; /* /Make sure it is NUL-terminated */
  602. last=strrchr(extraPath,'\\');
  603. if (last==0) last=strrchr(extraPath,'/');
  604. if (last && twice) {
  605. last[0]=0;
  606. last=strrchr(extraPath,'\\');
  607. if (last==0) last=strrchr(extraPath,'/');
  608. if (last) {
  609. last[0]=0;
  610. last=strrchr(extraPath,'\\');
  611. if (last==0) last=strrchr(extraPath,'/');
  612. }
  613. }
  614. if (last) last[1]=0;
  615. if (twice) {
  616. strcat(extraPath,"resources");
  617. strcat(extraPath,separator);
  618. } else {
  619. strcat(extraPath,"DymosimResources");
  620. strcat(extraPath,separator);
  621. }
  622. dymosimResourceLocation=extraPath;
  623. }
  624. first=0;
  625. }
  626. return dymosimResourceLocation ? dymosimResourceLocation : "DymosimResources/";
  627. }
  628. DYMOLA_STATIC double DYNhomotopy(double actual, double simple,struct DYNInstanceData*did_) {
  629. DymolaHomotopyUsed=1;
  630. return simple*(1-DymolaHomotopyLambda)+actual*DymolaHomotopyLambda;
  631. }
  632. DYMOLA_STATIC void dymosimSetResources(const char*s) {
  633. dymosimResourceLocation=s;
  634. }
  635. static void handleevent4funcMinor(struct DYNInstanceData*did_,const char*rele,const char*sube,int index, int PrintEvent2,int ltz,int invres) {
  636. handleevent4(rele,sube,&QL_[index], &Qp_[index-1],&Qn_[index-1],EPS_*Qscaled_[index-1],QRel_[index-1],Init_, PrintEvent2,&AnyEvent_,ltz,invres,Qenable_[index],LargeEPS_*Qscaled_[index-1],Iter>SlowIter_);
  637. }
  638. static void handleevent4func(struct DYNInstanceData*did_,const char*rele,const char*sube,int index, int PrintEvent2,int ltz,int invres) {
  639. handleevent5(rele,sube,&QL_[index], &Qp_[index-1],&Qn_[index-1],EPS_*Qscaled_[index-1],QRel_[index-1],Init_, PrintEvent2,&AnyEvent_,&AnyDEvent_,ltz,invres,Qenable_[index],LargeEPS_*Qscaled_[index-1],Iter>SlowIter_);
  640. }
  641. static Dymola_bool handleevent4Sfunc(struct DYNInstanceData*did_,const char*rele,const char*sube,double*QZV,int index, int incross,double Time,int PrintEvent2,int ltz,int invres) {
  642. Dymola_bool AE=0;
  643. Dymola_bool res;
  644. res=handleevent4S(rele,sube,
  645. &QL_[index],&Qp_[index-1],&Qn_[index-1],EPS_,QRel_[index-1],&QZV[2*(index)-2],Init_,DYNEvent,incross,PrintEvent2,&AE,ltz,invres,&Qenable_[index],LargeEPS_,Iter>SlowIter_,DYNTime);
  646. if (AE) {AnyEvent_=1;AnyIEvent_=1;}
  647. return res;
  648. }
  649. static int DYNIncrementFExternal() {
  650. AssertModelicaF(
  651. #ifdef NSizeOfFunctionStack
  652. FunctionExternalContext_<NSizeOfFunctionStack
  653. #else
  654. 0
  655. #endif
  656. ,"", "Out of stack for external objects in functions; see documentation to change.");
  657. return FunctionExternalContext_++;
  658. }
  659. #if defined(DYMOSIM)
  660. LIBDS_API double PositiveImpulse(int, double, double,int);
  661. LIBDS_API double SymmetricImpulse(int, double, int);
  662. LIBDS_API double DiracImpulse(int, double, double, int);
  663. LIBDS_API double DiracIntegral(int, double, double , int);
  664. LIBDS_API double HeaviSide(int, double, double, int);
  665. static void InitI(struct DYNInstanceData* did_,int,int);
  666. #endif
  667. #if defined(_MSC_VER)
  668. #if !DymolaGlobalOptimizations_
  669. /* Visual C++ does not work well for large models with global optimization.
  670. Remove at your own risk */
  671. #pragma optimize( "g", off )
  672. #elif DymolaGlobalOptimizations_ == 2
  673. #pragma optimize( "g", on )
  674. #endif
  675. #endif
  676. #if defined(DS_EMBEDDED)
  677. #include <dsembedded.c>
  678. #endif
  679. #if defined(DYNCALLFMUREINIT)
  680. DYMOLA_STATIC void DelayedUpdateReinit(double*time, double* X_, double* W_,double* U_,double* Y_, struct DYNInstanceData*did_);
  681. #endif
  682. DYMOLA_STATIC void equations_(int *idemand_, int *icall_,
  683. double *time, double X_[], double XD_[], double U_[], \
  684. double DP_[], int IP_[], Dymola_bool LP_[], \
  685. double F_[], double Y_[], double W_[], double QZ_[],
  686. double duser_[], int iuser_[], void*cuser_[], struct DYNInstanceData* did_,
  687. int *QiErr, int tid)
  688. {
  689. /* End dsblock1.c */