NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
LTENR_PropagationModel.c
1/************************************************************************************
2* Copyright (C) 2023 *
3* TETCOS, Bangalore. India *
4* *
5* Tetcos owns the intellectual property rights in the Product and its content. *
6* The copying, redistribution, reselling or publication of any or all of the *
7* Product or its content without express prior written consent of Tetcos is *
8* prohibited. Ownership and / or any other right relating to the software and all *
9* intellectual property rights therein shall remain at all times with Tetcos. *
10* *
11* This source code is licensed per the NetSim license agreement. *
12* *
13* No portion of this source code may be used as the basis for a derivative work, *
14* or used, for any purpose other than its intended use per the NetSim license *
15* agreement. *
16* *
17* This source code and the algorithms contained within it are confidential trade *
18* secrets of TETCOS and may not be used as the basis for any other software, *
19* hardware, product or service. *
20* *
21* Author: PV / SS *
22* Standard: TR 38.901(Release 16) *
23* Updated: 28-Aug-20 *
24* ----------------------------------------------------------------------------------*/
25
26#include "main.h"
27#include "stdafx.h"
28#include "LTENR_PHY.h"
29#include "LTENR_PropagationModel.h"
30#include "PropagationModel.h"
31#include "MobilityInterface.h"
32#include "NetSim_utility.h"
33
34#define c (3.0 * pow(10, 8))
35#define PI 3.1415
36#define RANDOM_01 (double)rand()/(double)RAND_MAX;
37
38static double calculate_distance3D(double distance2D, double height_BS, double height_UT)
39{
40 double distance3D;
41 // The 2D Distance calculation assumes the UE and gNB are in the same plane (aka Z is same for both)
42 // And only the heights are used for Z axis variations.
43 // Modify the distance calculations if Z co-ordinate varies for gNB and UE
44 distance3D = pow((pow((distance2D), 2) + pow((height_BS - height_UT), 2)), 0.5);
45 return distance3D;
46}
47
48
49static double discrete_uniform_dist(double values[], int count)
50{
51 int lower, upper, random;
52 lower = 1;
53 upper = count;
54 random = (rand() % (upper - lower + 1)) + lower;
55
56 if (random == 1)
57 return values[0];
58 else if (random == 2)
59 return values[1];
60 else if (random == 3)
61 return values[2];
62 else if (random == 4)
63 return values[3];
64 else
65 return 0;
66}
67
68
69static double log_normal_distribution(ptrLTENR_PROPAGATIONINFO info, double std)
70{
71 double ldRandomNumber = 0.0;
72 double fFac, fRsq, fV1, fV2;
73 double st, phase, loss;
74
75 if (info->SHADOWVAR.isConstructiveShadow == 0)
76 {
77 do
78 {
79 ldRandomNumber = RANDOM_01;
80 fV1 = (double)(2.0 * ldRandomNumber - 1.0);
81 //calculate the Random number from this function
82 ldRandomNumber = RANDOM_01;
83 fV2 = (double)(2.0 * ldRandomNumber - 1.0);
84 fRsq = fV1 * fV1 + fV2 * fV2;
85 } while (fRsq >= 1.0 || fRsq == 0.0);
86
87 fFac = (double)(sqrt(-2.0 * log(fRsq) / fRsq));
88 info->SHADOWVAR.Gset = fV1 * fFac;
89 info->SHADOWVAR.Iset = fV2 * fFac;
90
91 st = info->SHADOWVAR.Gset; //st = Gset || Iset;
92 info->SHADOWVAR.isConstructiveShadow = 1;
93 }
94 else
95 {
96 st = info->SHADOWVAR.Iset;
97 info->SHADOWVAR.isConstructiveShadow = 0;
98 }
99
100 phase = RANDOM_01;
101 if (phase <= 0.5)
102 loss = -1 * std * st;
103 else
104 loss = std * st;
105
106 return loss;
107}
108
109
110/** Error inverse Function for Normal Distribution */
111static long double ErrorFunc(double p)
112{
113 return (1.0968 * (sqrt(PI) * 0.5 * (p + (PI * pow(p, 3)) / 12 + (7 * pow(PI, 2) * pow(p, 5)) / 480 +
114 (127 * pow(PI, 3) * pow(p, 7)) / 40320 +
115 (4369 * pow(PI, 4) * pow(p, 9)) / 5806080 +
116 (34807 * pow(PI, 5) * pow(p, 11)) / 182476800)));
117}
118
119
120static double normal_distribution(double args1, double args2)
121{
122 double fFirstArg, fSecondArg, fRandomNumber, fDistOut;
123
124 fFirstArg = args1;
125 fSecondArg = args2;
126 fRandomNumber = RANDOM_01;
127 fDistOut = (double)(fFirstArg + fSecondArg * sqrt(2) * ErrorFunc(2 * fRandomNumber - 1));
128 return fDistOut;
129}
130
131
132static double uniform_distribution(double args1, double args2)
133{
134 double fFirstArg, fSecondArg, fRandomNumber, fDistOut;
135 fFirstArg = args1;
136 fSecondArg = args2;
137 fRandomNumber = RANDOM_01;
138 fDistOut = fFirstArg + (fSecondArg - fFirstArg) * fRandomNumber;
139 return fDistOut;
140}
141
142
143static double calculate_LOS_probability(ptrLTENR_PROPAGATIONINFO info)
144{
145 double LOS_probability, chUT = 0;
146 double hUT;
147 double distance2D_out = 0;
148
149 if (info->uePosition == LTENR_LOCATION_OUTDOOR && info->gnbPosition != LTENR_LOCATION_INDOOR)
150 distance2D_out = info->dist2D;
151
152 else if (info->uePosition == LTENR_LOCATION_INDOOR && info->gnbPosition != LTENR_LOCATION_INDOOR)
153 distance2D_out = info->dist2Doutdoor;
154
155 switch (info->currentScenario)
156 {
157 case LTENR_SCENARIO_RMA:
158 {
159 if (distance2D_out <= 10)
160 LOS_probability = 1;
161 else
162 LOS_probability = exp(-(distance2D_out - 10) / 1000);
163
164 return LOS_probability;
165 }
166 break;
167
168 case LTENR_SCENARIO_UMA:
169 {
170 hUT = info->propagationConfig->UE_height;
171
172 if (distance2D_out <= 18)
173 LOS_probability = 1;
174 else
175 {
176 if (hUT <= 13)
177 chUT = 0;
178 else if (13 <= hUT && hUT <= 23)
179 chUT = pow(((hUT - 13) / 10), 1.5);
180
181 LOS_probability = ((18 / distance2D_out) +
182 (exp(-(distance2D_out / 63)) * (1 - (18 / distance2D_out)))) *
183 (1 + (chUT * (5 / 4) * pow((distance2D_out / 100), 3) *
184 exp(-(distance2D_out / 150))));
185 }
186 return LOS_probability;
187 }
188 break;
189
190 case LTENR_SCENARIO_UMI:
191 {
192 if (distance2D_out <= 18)
193 LOS_probability = 1;
194 else
195 LOS_probability = ((18 / distance2D_out) + (exp(-(distance2D_out / 36)) *
196 (1 - (18 / distance2D_out))));
197 return LOS_probability;
198 }
199 break;
200
201 case LTENR_SCENARIO_INH:
202 {
203 double distance2D_in;
204 distance2D_in = info->dist2D;
205
206 switch (info->propagationConfig->indoor_type)
207 {
208 case LTENR_INH_MIXED_OFFICE:
209 {
210 if (distance2D_in <= 1.2)
211 LOS_probability = 1;
212 else if (1.2 <= distance2D_in && distance2D_in <= 6.5)
213 LOS_probability = exp(-(distance2D_in - 1.2) / 4.7);
214 else
215 LOS_probability = exp(-(distance2D_in - 6.5) / 32.6) * 0.32;
216
217 return LOS_probability;
218 }
219 break;
220
221 case LTENR_INH_OPEN_OFFICE:
222 {
223 if (distance2D_in <= 5)
224 LOS_probability = 1;
225 else if (5 <= distance2D_in && distance2D_in <= 49)
226 LOS_probability = exp(-(distance2D_in - 5) / 70.8);
227 else
228 LOS_probability = exp(-(distance2D_in - 49) / 211.7) * 0.54;
229
230 return LOS_probability;
231 }
232 break;
233
234 default:
235 {
236 fnNetSimError("Unknown INDOOR_OFFICE Type %d!\n", info->propagationConfig->indoor_type);
237 return 0;
238 }
239 break;
240 }
241 }
242 break;
243
244 default:
245 {
246 fnNetSimError("Unknown Scenario %d in function %s\n", info->currentScenario, __FUNCTION__);
247 return 0;
248 }
249 break;
250 }
251}
252
253
254static LTENR_LOS_NLOS_STATE check_los_state(ptrLTENR_PROPAGATIONINFO info)
255{
256 double LOS_probability;
257 double r = RANDOM_01;
258 if (info->propagationConfig->los_mode != LTENR_LOS_MODE_USER_DEFINED)
259 LOS_probability = calculate_LOS_probability(info);
260 else
261 LOS_probability = info->propagationConfig->los_probability;
262
263 if (r <= LOS_probability)
264 return LTENR_STATE_LOS;
265 else
266 return LTENR_STATE_NLOS;
267}
268
269
270static double g_UMa(double d_2D)
271{
272 if (d_2D <= 18)
273 return 0;
274 else
275 return ((5 / 4) * pow((d_2D / 100), 3) * exp(-d_2D / 150));
276}
277
278
279static double C_UMa(double d_2D, double hUT)
280{
281 if (hUT < 13)
282 return 0;
283 else if (13 <= hUT && hUT <= 23)
284 return pow(((hUT - 13) / 10), 1.5) * g_UMa(d_2D);
285 else
286 {
287 fnNetSimError("Height of UT beyond range!\n");
288 return 0;
289 }
290}
291
292
293static double calculate_pathloss_only(ptrLTENR_PROPAGATIONINFO info)
294{
295 double fc = info->frequency_gHz;
296 double PL1, PL2, PL3, distance2D, distance3D, distanceBP;
297 double pathloss_RMa_LOS = 0, pathloss_RMa_NLOS = 0;
298 double pathloss_UMa_LOS = 0, pathloss_UMa_NLOS = 0;
299 double pathloss_UMi_LOS = 0, pathloss_UMi_NLOS = 0;
300 double pathloss_InH_LOS = 0, pathloss_InH_NLOS = 0;
301
302 double hBS, hUT, W, h;
303 double h_effectiveEnv, hBS_effective, hUT_effective;
304
305 distance2D = info->dist2D;
306 distance3D = info->dist3D;
307
308 LTENR_LOS_NLOS_STATE state = info->propagationConfig->state;
309
310 switch (info->currentScenario)
311 {
312 case LTENR_SCENARIO_RMA:
313 {
314 hBS = info->propagationConfig->gNB_height;
315 hUT = info->propagationConfig->UE_height;
316 W = info->propagationConfig->street_width;
317 h = info->propagationConfig->buildings_height;
318
319 distanceBP = 2 * PI * hBS * hUT * ((fc * 1000000000) / c);
320
321 PL1 = (20 * log10(40 * PI * distance3D * fc / 3)) + fmin((0.03 * pow(h, 1.72)), 10) *
322 log10(distance3D) - fmin((0.044 * pow(h, 1.72)), 14.77) + (0.002 * log10(h) * distance3D);
323 PL2 = PL1 + (40 * log10(distance3D / distanceBP)); //PL1(distanceBP) = PL1
324
325 if (10 <= distance2D && distance2D <= distanceBP)
326 pathloss_RMa_LOS = PL1;
327 else if (distanceBP <= distance2D && distance2D <= 10000)
328 pathloss_RMa_LOS = PL2;
329 else if (distance2D > 10000)
330 pathloss_RMa_LOS = -1*NEGATIVE_DBM; // Zero power in dBm is denoted as -1000 for calculation purposes.
331
332 if (state == LTENR_STATE_LOS)
333 return pathloss_RMa_LOS;
334
335 else
336 {
337 PL3 = 161.04 - (7.1 * log10(W)) + (7.5 * log10(h)) -
338 ((24.37 - 3.7 * pow((h / hBS), 2)) * log10(hBS)) +
339 ((43.42 - 3.1 * log10(hBS)) * (log10(distance3D) - 3)) +
340 (20 * log10(fc)) - ((3.2 * pow((log10(11.75 * hUT)), 2) - 4.97));
341 if (distance2D > 5000)
342 distance2D = 5000;
343
344
345 if (10 <= distance2D && distance2D <= 5000)
346 pathloss_RMa_NLOS = fmax(pathloss_RMa_LOS, PL3);
347
348 return pathloss_RMa_NLOS;
349 }
350 }
351 break;
352
353 case LTENR_SCENARIO_UMA:
354 {
355 hBS = info->propagationConfig->gNB_height;
356 hUT = info->propagationConfig->UE_height;
357
358 double prob = 1 / (1 + C_UMa(distance2D, hUT));
359 double r = RANDOM_01;
360
361 if (r <= prob)
362 h_effectiveEnv = 1.0;
363 else
364 {
365 double values[4];
366
367 if ((hUT - 1.5) <= 12)
368 h_effectiveEnv = hUT - 1.5;
369 else if (12 < (hUT - 1.5) && (hUT - 1.5) <= 15)
370 {
371 values[0] = 12;
372 values[1] = hUT - 1.5;
373 h_effectiveEnv = discrete_uniform_dist(values, 2);
374 }
375 else if (15 < (hUT - 1.5) && (hUT - 1.5) <= 18)
376 {
377 values[0] = 12;
378 values[1] = 15;
379 values[2] = hUT - 1.5;
380 h_effectiveEnv = discrete_uniform_dist(values, 3);
381 }
382 else
383 {
384 values[0] = 12;
385 values[1] = 15;
386 values[2] = 18;
387 values[3] = hUT - 1.5;
388 h_effectiveEnv = discrete_uniform_dist(values, 4);
389 }
390 }
391
392 hBS_effective = hBS - h_effectiveEnv;
393 hUT_effective = hUT - h_effectiveEnv;
394
395 distanceBP = 4 * hBS_effective * hUT_effective * ((fc * 1000000000) / c);
396
397 PL1 = 28.0 + (22 * log10(distance3D)) + (20 * log10(fc));
398 PL2 = 28.0 + (40 * log10(distance3D)) + (20 * log10(fc)) - (9 * log10(pow(distanceBP, 2) +
399 pow((hBS - hUT), 2)));
400
401 if (10 <= distance2D && distance2D <= distanceBP)
402 pathloss_UMa_LOS = PL1;
403 else if (distanceBP <= distance2D && distance2D <= 5000)
404 pathloss_UMa_LOS = PL2;
405 else if (distance2D > 5000)
406 pathloss_UMa_LOS = -1 * NEGATIVE_DBM; // Zero power in dBm is denoted as -1000 for calculation purposes.
407
408 if (state == LTENR_STATE_LOS)
409 return pathloss_UMa_LOS;
410
411 else
412 {
413 PL3 = 13.54 + (39.08 * log10(distance3D)) + (20 * log10(fc)) - (0.6 * (hUT - 1.5));
414 if (distance2D > 5000)
415 distance2D = 5000;
416
417 if (10 <= distance2D && distance2D <= 5000)
418 pathloss_UMa_NLOS = fmax(pathloss_UMa_LOS, PL3);
419
420 return pathloss_UMa_NLOS;
421 }
422 }
423 break;
424
425 case LTENR_SCENARIO_UMI:
426 {
427 hBS = info->propagationConfig->gNB_height;
428 hUT = info->propagationConfig->UE_height;
429 h_effectiveEnv = 1.0;
430 hBS_effective = hBS - h_effectiveEnv;
431 hUT_effective = hUT - h_effectiveEnv;
432
433 distanceBP = 4 * hBS_effective * hUT_effective * ((fc * 1000000000) / c);
434
435 PL1 = 32.4 + (21 * log10(distance3D)) + (20 * log10(fc));
436 PL2 = 32.4 + (40 * log10(distance3D)) + (20 * log10(fc)) - (9.5 * log10(pow(distanceBP, 2) +
437
438 pow((hBS - hUT), 2)));
439 if (distance2D > 5000)
440 pathloss_UMi_LOS = -1 * NEGATIVE_DBM; // Zero power in dBm is denoted as -1000 for calculation purposes.
441 else if (10 <= distance2D && distance2D <= distanceBP)
442 pathloss_UMi_LOS = PL1;
443 else if (distanceBP <= distance2D && distance2D <= 5000)
444 pathloss_UMi_LOS = PL2;
445
446 if (state == LTENR_STATE_LOS)
447 return pathloss_UMi_LOS;
448
449 else
450 {
451 PL3 = (35.3 * log10(distance3D)) + 22.4 + (21.3 * log10(fc)) - (0.3 * (hUT - 1.5));
452 if (distance2D > 5000)
453 distance2D = 5000;
454
455 if (10 <= distance2D && distance2D <= 5000)
456 pathloss_UMi_NLOS = fmax(pathloss_UMi_LOS, PL3);
457
458 return pathloss_UMi_NLOS;
459 }
460 }
461 break;
462
463 case LTENR_SCENARIO_INH:
464 {
465 hBS = info->propagationConfig->gNB_height;
466 hUT = info->propagationConfig->UE_height;
467
468 pathloss_InH_LOS = 32.4 + (17.3 * log10(distance3D)) + (20 * log10(fc));
469
470 if (state == LTENR_STATE_LOS)
471 return pathloss_InH_LOS;
472
473 else
474 {
475 PL3 = (38.3 * log10(distance3D)) + 17.30 + (24.9 * log10(fc));
476 pathloss_InH_NLOS = fmax(pathloss_InH_LOS, PL3);
477 return pathloss_InH_NLOS;
478 }
479 }
480 break;
481
482 default:
483 {
484 fnNetSimError("Unknown Scenario %d in funtion %s\n", info->currentScenario, __FUNCTION__);
485 return 0;
486 }
487 break;
488 }
489}
490
491static double calculate_shadow_fading(ptrLTENR_PROPAGATIONINFO info)
492{
493 double fc = info->frequency_gHz;
494 double hBS, hUT, distanceBP, shadowFadingStd = 0;
495 double distance2D = info->dist2D;
496
497 LTENR_LOS_NLOS_STATE state = info->propagationConfig->state;
498
499 switch (info->currentScenario)
500 {
501 case LTENR_SCENARIO_RMA:
502 {
503 hBS = info->propagationConfig->gNB_height;
504 hUT = info->propagationConfig->UE_height;
505
506 distanceBP = 2 * PI * hBS * hUT * ((fc * 1000000000) / c);
507
508 if (state == LTENR_STATE_LOS)
509 {
510 if (10 <= distance2D && distance2D <= distanceBP)
511 shadowFadingStd = 4;
512 else if (distanceBP <= distance2D && distance2D <= 10000)
513 shadowFadingStd = 6;
514 }
515 else
516 shadowFadingStd = 8;
517
518 return log_normal_distribution(info, shadowFadingStd);
519 }
520 break;
521
522 case LTENR_SCENARIO_UMA:
523 {
524 if (state == LTENR_STATE_LOS)
525 shadowFadingStd = 4;
526 else
527 shadowFadingStd = 6;
528
529 return log_normal_distribution(info, shadowFadingStd);
530 }
531 break;
532
533 case LTENR_SCENARIO_UMI:
534 {
535 if (state == LTENR_STATE_LOS)
536 shadowFadingStd = 4;
537 else
538 shadowFadingStd = 7.82;
539
540 return log_normal_distribution(info, shadowFadingStd);
541 }
542 break;
543
544 case LTENR_SCENARIO_INH:
545 {
546 if (state == LTENR_STATE_LOS)
547 shadowFadingStd = 3;
548 else
549 shadowFadingStd = 8.03;
550
551 return log_normal_distribution(info, shadowFadingStd);
552 }
553 break;
554
555 default:
556 {
557 fnNetSimError("Unknown Scenario %d in function %s\n", info->currentScenario, __FUNCTION__);
558 return 0;
559 }
560 break;
561 }
562}
563
564static double calculate_O2I_Buildingpenetrationloss(ptrLTENR_PROPAGATIONINFO info)
565{
566 double f = info->frequency_gHz;
567 double PL_tw, PL_in, std_p;
568 double O2Iloss = 0;
569 double L_glass = 2 + (0.2 * f);
570 double L_iirglass = 23 + (0.3 * f);
571 double L_concrete = 5 + (4 * f);
572
573 double dist2D_in = 0.0;
574 if (info->propagationConfig->pathLossModel == LTENR_PATHLOSS_MODEL_3GPP38_901_7_4_1)
575 {
576 if (info->currentScenario == LTENR_SCENARIO_UMA || info->currentScenario == LTENR_SCENARIO_UMI)
577 dist2D_in = fmin(uniform_distribution(0, 25), uniform_distribution(0, 25));
578 else if (info->currentScenario == LTENR_SCENARIO_RMA)
579 dist2D_in = fmin(uniform_distribution(0, 10), uniform_distribution(0, 10));
580 }
581
582 switch (info->propagationConfig->o2iBuildingPenetrationModel)
583 {
584 case LTENR_O2IBUILDINGPENETRATION_MODEL_NONE:
585 O2Iloss = 0;
586 break;
587 case LTENR_O2IBUILDINGPENETRATION_MODEL_LOW_LOSS:
588 {
589 PL_tw = 5 - 10 * log10((0.3 * pow(10, (-L_glass / 10))) + (0.7 * pow(10, (-L_concrete / 10))));
590 PL_in = 0.5 * dist2D_in;
591 std_p = 4.4;
592
593 O2Iloss = PL_tw + PL_in + abs((int)normal_distribution(0, std_p));
594 }
595 break;
596 case LTENR_O2IBUILDINGPENETRATION_MODEL_HIGH_LOSS:
597 {
598 PL_tw = 5 - 10 * log10((0.7 * pow(10, (-L_iirglass / 10))) + (0.3 * pow(10, (-L_concrete / 10))));
599 PL_in = 0.5 * dist2D_in;
600 std_p = 6.5;
601
602 O2Iloss = PL_tw + PL_in + abs((int)normal_distribution(0, std_p));
603 }
604 break;
605 default:
606 {
607 fnNetSimError("Unknown O2I building penetration model %s in function %s\n",
608 strLTENR_O2IBUILDINGPENETRATION_MODEL[info->propagationConfig->o2iBuildingPenetrationModel],
609 __FUNCTION__);
610 O2Iloss = 0.0;
611 }
612 break;
613 }
614 return O2Iloss;
615}
616
617static void decideIndoorOutDoor(ptrLTENR_PROPAGATIONINFO info)
618{
619 if (fnMobility_isPosInsideAnyBuilding(&info->uePos) != 0)
620 info->uePosition = LTENR_LOCATION_INDOOR;
621 else
622 info->uePosition = LTENR_LOCATION_OUTDOOR;
623
624 if (fnMobility_isPosInsideAnyBuilding(&info->gnbPos))
625 info->gnbPosition = LTENR_LOCATION_INDOOR;
626 else
627 info->gnbPosition = LTENR_LOCATION_OUTDOOR;
628}
629
630static void calculateDistance(ptrLTENR_PROPAGATIONINFO info)
631{
632 info->dist2D = fn_NetSim_Utilities_CalculateDistance(&info->gnbPos, &info->uePos);
633 if (info->uePosition == LTENR_LOCATION_INDOOR && info->gnbPosition != LTENR_LOCATION_INDOOR)
634 {
635 info->dist2Dindoor = fnMobility_findIndoorDistance(&info->gnbPos, &info->uePos);
636 info->dist2Doutdoor = info->dist2D - info->dist2Dindoor;
637 }
638}
639
640static void recalculate_localvar(ptrLTENR_PROPAGATIONINFO info)
641{
642 info->frequency_gHz = info->centralFrequency_MHz / 1000.0;
643
644 decideIndoorOutDoor(info);
645 calculateDistance(info);
646
647 if (info->gnbPosition != LTENR_LOCATION_INDOOR)
648 info->currentScenario = info->propagationConfig->outScenario;
649 else
650 info->currentScenario = info->propagationConfig->inScenario;
651
652 switch (info->currentScenario)
653 {
654 case LTENR_SCENARIO_RMA:
655 {
656 if (info->dist2D < 10)
657 info->dist2D = 10;
658
659 info->dist3D = calculate_distance3D(info->dist2D, info->propagationConfig->gNB_height,
660 info->propagationConfig->UE_height);
661 }
662 break;
663 case LTENR_SCENARIO_UMA:
664 {
665 if (info->dist2D < 10)
666 info->dist2D = 10;
667
668 info->dist3D = calculate_distance3D(info->dist2D, info->propagationConfig->gNB_height,
669 info->propagationConfig->UE_height);
670 }
671 break;
672 case LTENR_SCENARIO_UMI:
673 {
674 if (info->dist2D < 10)
675 info->dist2D = 10;
676
677 info->dist3D = calculate_distance3D(info->dist2D, info->propagationConfig->gNB_height,
678 info->propagationConfig->UE_height);
679 }
680 break;
681 case LTENR_SCENARIO_INH:
682 {
683 if (info->dist2D < 1)
684 info->dist2D = 1;
685
686 info->dist3D = calculate_distance3D(info->dist2D, info->propagationConfig->gNB_height,
687 info->propagationConfig->UE_height);
688 }
689 break;
690
691 default:
692 fnNetSimError("Unknown Scenario %d in function %s!\n", info->currentScenario, __FUNCTION__);
693 break;
694 }
695}
696
697_declspec(dllexport) void LTENR_Propagation_TotalLoss(ptrLTENR_PROPAGATIONINFO info)
698{
699 recalculate_localvar(info);
700
701 info->propagationConfig->state = check_los_state(info);
702
703 if (info->propagationConfig->isPathLossEnabled)
704 {
705 if (info->propagationConfig->pathLossModel == LTENR_PATHLOSS_MODEL_3GPP38_901_7_4_1)
706 info->dPathLoss = calculate_pathloss_only(info);
707 else if (info->propagationConfig->pathLossModel == LTENR_PATHLOSS_MODEL_LOG_DISTANCE)
708 info->dPathLoss = (-1) * _propagation_calculate_logdistancepathloss(info->propagationConfig->pathLossExponent,
709 info->dist3D, info->centralFrequency_MHz, info->propagationConfig->d0);
710 else
711 {
712 fnNetSimError("5G - Unknown pathloss model %d in %s\n",
713 info->propagationConfig->pathLossModel, __FUNCTION__);
714 info->dPathLoss = 0;
715 }
716 }
717 else info->dPathLoss = 0;
718
719 if (info->propagationConfig->isShadowFadingEnabled)
720 info->dShadowFadingLoss = calculate_shadow_fading(info);
721 else if (info->propagationConfig->shadowFadingModel == LTENR_SHADOWFADING_MODEL_LOGNORMAL)
722 info->dShadowFadingLoss = _propagation_calculate_lognormalshadow(info->propagationConfig->standardDeviation,
723 &info->propagationConfig->Gset, &info->propagationConfig->iSet);
724 else
725 info->dShadowFadingLoss = 0;
726
727 if (info->propagationConfig->isO2IBuildingPenetrationLossEnabled &&
728 info->uePosition == LTENR_LOCATION_INDOOR &&
729 info->currentScenario != LTENR_SCENARIO_INH)
730 info->dO2ILoss = calculate_O2I_Buildingpenetrationloss(info);
731 else
732 info->dO2ILoss = 0;
733
734 if (info->propagationConfig->additionalLossModel == LTENR_ADDITIONAL_LOSS_MATLAB)
735 info->dAdditionalLoss = netsim_matlab_calculate_loss(info);
736 else
737 info->dAdditionalLoss = 0;
738
739 info->dTotalLoss = info->dPathLoss + info->dShadowFadingLoss + info->dO2ILoss + info->dAdditionalLoss;
740
741#ifdef LTENR_PROPAGATION_LOG
742 print_ltenr_log("\tPropagation Model starts for gNB = %d and UE = %d\n", info->gnbId, info->ueId);
743 print_ltenr_log("\t\t2D Distance = %lf m\n", info->dist2D);
744 print_ltenr_log("\t\t3D Distance = %lf m\n", info->dist3D);
745 print_ltenr_log("\t\tChannel condition = %s\n", strLTENR_STATE[info->propagationConfig->state]);
746 print_ltenr_log("\t\tTotal Propagation Loss = %lf dB\n", info->dTotalLoss);
747 print_ltenr_log("\t\t\tPathLoss = %lf dB\n", info->dPathLoss);
748 print_ltenr_log("\t\t\tShadow Fading Loss = %lf dB\n", info->dShadowFadingLoss);
749 print_ltenr_log("\t\t\tO2I Penetration Loss = %lf dB\n", info->dO2ILoss);
750#endif // LTENR_PROPAGATION_LOG
751}