1#include "NTN_PropagationModel.h"
2#include "LTENR_PropagationModel.h"
7#define EARTH_RADIUS 6371000
8#define BOLTZMANN -228.6
9#define CIR_MW_TO_DBM(mw) ((mw) <= ZERO_MW?NEGATIVE_DBM:-10.0*log10(mw))
10#define CIR_DBM_TO_MW(dbm) ((dbm) == NEGATIVE_DBM? 0.0: pow(10.0,(-dbm)/10.0))
12#define NTN_RX_ANTENNA_TEMPERATURE 290
14static bool isNTNScenarioVar =
false;
15static ptrNTN_PROPAGATIONCONFIG ntnInfo = NULL;
20 return isNTNScenarioVar;
23void setNTNpropagationInfo(ptrNTN_PROPAGATIONCONFIG propagation) {
24 ntnInfo = propagation;
27ptrNTN_PROPAGATIONCONFIG getNTN_PropInfo()
34 isNTNScenarioVar =
true;
39double calculateSlantRange(
double altitude,
double elevationAngle_rad)
41 double sinAlpha = sin(elevationAngle_rad);
42 double d = sqrt(pow(EARTH_RADIUS * sinAlpha, 2) + pow(altitude, 2) + 2 * altitude * EARTH_RADIUS) - EARTH_RADIUS * sinAlpha;
46double calculateNTN_SNR(ptrLTENR_PROPAGATIONINFO propInfo,
double beamformingGain) {
47 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
49 eirp_dBW = ntnInfo->eirpDensity + MW_TO_DBM(ntnInfo->channelBandwidth);
51 ntnInfo->eirp_dBW = eirp_dBW;
52 double B_db = MW_TO_DBM(ntnInfo->channelBandwidth * pow(10, 6));
53 snr = eirp_dBW + propInfo->angularAntennaGain_dB + propInfo->rxG_T - BOLTZMANN - propInfo->dTotalLoss - B_db + beamformingGain;
58double calculateFreeSpacePathLoss(ptrLTENR_PROPAGATIONINFO propInfo)
60 NETSIM_ID ueId = propInfo->ueId;
62 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
64 double altitude = DEVICE_POSITION(ntnInfo->ntnId)->Z;
66 propInfo->slantHeight = calculateSlantRange(altitude, propInfo->elevationAngle_rad);
68 return 32.45 + 20 * log10(propInfo->centralFrequency_GHz) + 20 * log10(propInfo->slantHeight);
71static double NTN_log_normal_distribution(ptrNTN_PROPAGATIONCONFIG info,
double std)
73 double ldRandomNumber = 0.0;
74 double fFac, fRsq, fV1, fV2;
75 double st, phase, loss;
77 if (info->SHADOWVAR.isConstructiveShadow == 0)
81 ldRandomNumber = RANDOM_01;
82 fV1 = (double)(2.0 * ldRandomNumber - 1.0);
84 ldRandomNumber = RANDOM_01;
85 fV2 = (double)(2.0 * ldRandomNumber - 1.0);
86 fRsq = fV1 * fV1 + fV2 * fV2;
87 }
while (fRsq >= 1.0 || fRsq == 0.0);
89 fFac = (double)(sqrt(-2.0 * log(fRsq) / fRsq));
90 info->SHADOWVAR.Gset = fV1 * fFac;
91 info->SHADOWVAR.Iset = fV2 * fFac;
93 st = info->SHADOWVAR.Gset;
94 info->SHADOWVAR.isConstructiveShadow = 1;
98 st = info->SHADOWVAR.Iset;
99 info->SHADOWVAR.isConstructiveShadow = 0;
104 loss = -1 * std * st;
111void calculateNTN_totalloss(ptrLTENR_PROPAGATIONINFO propInfo)
114 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
116 NETSIM_ID ueId = propInfo->ueId;
118 if (ntnInfo->pathLossModel == NTN_PATHLOSS_MODEL_FREE_SPACE)
120 propInfo->dPathLoss = calculateFreeSpacePathLoss(propInfo);
123 propInfo->dPathLoss = 0;
125 if (ntnInfo->shadowFadingModel == NTN_SHADOWFADING_MODEL_LOGNORMAL)
127 propInfo->dShadowFadingLoss = calculateNTNshadowloss(propInfo);
130 propInfo->dShadowFadingLoss = 0;
132 if (ntnInfo->clutterlossModel == NTN_CLUTTERLOSS_MODEL_TR38_811)
134 propInfo->dClutterLoss = calculateNTNclutterloss(propInfo);
137 propInfo->dClutterLoss = 0;
139 propInfo->dAdditionalLoss = ntnInfo->additionalLoss;
141 propInfo->dTotalLoss = propInfo->dPathLoss + propInfo->dShadowFadingLoss
142 + propInfo->dAdditionalLoss + propInfo->dClutterLoss;
146ptrBeamNode addBeamCenters(UINT beamCount)
148 char filename[BUFSIZ];
149 sprintf(filename,
"%s\\Default\\CenterPoints.csv", pszIOPath);
151 FILE* file = fopen(filename,
"r");
153 fprintf(stderr,
"Error opening file\n");
157 ptrBeamNode head = NULL;
158 ptrBeamNode tail = NULL;
166 while (fgets(buffer,
sizeof(buffer), file) != NULL) {
167 if (sscanf(buffer,
"%d,%lf,%lf,%d", &cellId, &x, &y, &channelId) == 4)
169 ptrBeamNode newBeam = (ptrBeamNode)malloc(
sizeof(BeamNode));
171 fprintf(stderr,
"Memory allocation failed\n");
175 newBeam->beamCoord = (NetSim_COORDINATES*)malloc(
sizeof(NetSim_COORDINATES));
178 newBeam->beamId = id;
179 newBeam->beamCoord->X = x;
180 newBeam->beamCoord->Y = y;
181 newBeam->beamChannelId = channelId;
182 newBeam->next = NULL;
189 tail->next = newBeam;
195 if (
id - 1 != beamCount)
197 fprintf(stderr,
"\nCount of beams not matching");
203void calculateNTNAntennaGain(ptrLTENR_PROPAGATIONINFO propInfo)
205 CalculateTheta(propInfo);
207 NETSIM_ID ueId = propInfo->ueId;
208 NetSim_COORDINATES* uePos = DEVICE_POSITION(ueId);
211 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
213 double k = 2 * M_PI * propInfo->centralFrequency_GHz * pow(10, 9) / (3 * pow(10, 8));
215 antennaGain = calculateAntennaGain(propInfo->theta_rad, k, ntnInfo->antennaAperture);
217 propInfo->angularAntennaGain_dB = antennaGain;
218 propInfo->netAntennaGain_dB = propInfo->angularAntennaGain_dB + ntnInfo->maxAntennaGain;
222static void updateNTN_elevationAngle(ptrLTENR_PROPAGATIONINFO propInfo)
224 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
226 double x1 = DEVICE_POSITION(ntnInfo->ntnId)->X;
227 double y1 = DEVICE_POSITION(ntnInfo->ntnId)->Y;
228 double z1 = DEVICE_POSITION(ntnInfo->ntnId)->Z;
230 double x2 = DEVICE_POSITION(propInfo->ueId)->X;
231 double y2 = DEVICE_POSITION(propInfo->ueId)->Y;
233 double dis = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
234 double theta = atan(z1 / dis);
235 propInfo->elevationAngle_rad = theta;
239void allocateInfo(ptrLTENR_PROPAGATIONINFO propInfo)
242 UINT layerCount = min(propInfo->downlink.txAntennaCount, propInfo->downlink.rxAntennaCount);
243 propInfo->downlink.rxPower_dbm = malloc(layerCount *
sizeof(
double));
244 propInfo->downlink.SNR_db = malloc(layerCount *
sizeof(
double));
245 propInfo->downlink.SINR_db = malloc(layerCount *
sizeof(
double));
246 propInfo->downlink.EB_by_N0 = malloc(layerCount *
sizeof(
double));
247 propInfo->downlink.InterferencePower_dbm = malloc(layerCount *
sizeof(
double));
248 propInfo->downlink.spectralEfficiency = malloc(layerCount *
sizeof(
double));
250 layerCount = min(propInfo->uplink.txAntennaCount, propInfo->uplink.rxAntennaCount);
252 propInfo->uplink.rxPower_dbm = malloc(layerCount *
sizeof(
double));
253 propInfo->uplink.SNR_db = malloc(layerCount *
sizeof(
double));
254 propInfo->uplink.SINR_db = malloc(layerCount *
sizeof(
double));
255 propInfo->uplink.EB_by_N0 = malloc(layerCount *
sizeof(
double));
256 propInfo->uplink.InterferencePower_dbm = malloc(layerCount *
sizeof(
double));
257 propInfo->uplink.spectralEfficiency = malloc(layerCount *
sizeof(
double));
260static void freeInfo(ptrLTENR_PROPAGATIONINFO propInfo)
262 if (!propInfo)
return;
264 free(propInfo->downlink.rxPower_dbm);
265 free(propInfo->downlink.SNR_db);
266 free(propInfo->downlink.SINR_db);
267 free(propInfo->downlink.EB_by_N0);
268 free(propInfo->downlink.InterferencePower_dbm);
269 free(propInfo->downlink.spectralEfficiency);
271 free(propInfo->uplink.rxPower_dbm);
272 free(propInfo->uplink.SNR_db);
273 free(propInfo->uplink.SINR_db);
274 free(propInfo->uplink.EB_by_N0);
275 free(propInfo->uplink.InterferencePower_dbm);
276 free(propInfo->uplink.spectralEfficiency);
280static void deepCopyPropagationInfo(ptrLTENR_PROPAGATIONINFO propInfo, ptrLTENR_PROPAGATIONINFO tempInfo)
282 if (!propInfo || !tempInfo) {
283 fprintf(stderr,
"PorpInfo not copied");
286 UINT layerCount = propInfo->downlink.layerCount;
288 propInfo->angularAntennaGain_dB = tempInfo->angularAntennaGain_dB;
289 propInfo->netAntennaGain_dB = tempInfo->netAntennaGain_dB;
290 propInfo->rxG_T = tempInfo->rxG_T;
291 propInfo->selectedBeamId = tempInfo->selectedBeamId;
293 propInfo->slantHeight = tempInfo->slantHeight;
294 propInfo->theta_rad = tempInfo->theta_rad;
295 propInfo->dPathLoss = tempInfo->dPathLoss;
296 propInfo->dShadowFadingLoss = tempInfo->dShadowFadingLoss;
297 propInfo->dAdditionalLoss = tempInfo->dAdditionalLoss;
298 propInfo->dClutterLoss = tempInfo->dClutterLoss;
299 propInfo->dTotalLoss = tempInfo->dTotalLoss;
300 propInfo->downlink.thermalNoise = tempInfo->downlink.thermalNoise;
302 for (
int layerId = 0; layerId < layerCount; layerId++)
304 propInfo->downlink.SNR_db[layerId] = tempInfo->downlink.SNR_db[layerId];
305 propInfo->downlink.rxPower_dbm[layerId] = tempInfo->downlink.rxPower_dbm[layerId];
306 propInfo->downlink.EB_by_N0[layerId] = tempInfo->downlink.EB_by_N0[layerId];
307 propInfo->downlink.spectralEfficiency[layerId] = tempInfo->downlink.spectralEfficiency[layerId];
308 propInfo->downlink.SINR_db[layerId] = tempInfo->downlink.SINR_db[layerId];
309 propInfo->downlink.InterferencePower_dbm[layerId] = tempInfo->downlink.InterferencePower_dbm[layerId];
312 layerCount = propInfo->uplink.layerCount;
314 for (
int layerId = 0; layerId < layerCount; layerId++)
316 propInfo->uplink.SNR_db[layerId] = tempInfo->uplink.SNR_db[layerId];
317 propInfo->uplink.rxPower_dbm[layerId] = tempInfo->uplink.rxPower_dbm[layerId];
318 propInfo->uplink.EB_by_N0[layerId] = tempInfo->uplink.EB_by_N0[layerId];
319 propInfo->uplink.spectralEfficiency[layerId] = tempInfo->uplink.spectralEfficiency[layerId];
320 propInfo->uplink.SINR_db[layerId] = tempInfo->uplink.SINR_db[layerId];
321 propInfo->uplink.InterferencePower_dbm[layerId] = tempInfo->uplink.InterferencePower_dbm[layerId];
326void NTN_BestBeamSelectionAlgorithm(ptrLTENR_PROPAGATIONINFO propInfo,
int CA_ID, UINT layerId)
328 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
330 ptrBeamNode tempbeamList = ntnInfo->beamList;
331 double bestSNR = NEGATIVE_DBM, snr = NEGATIVE_DBM;
334 updateNTNBandwidth(propInfo);
335 updateNTN_elevationAngle(propInfo);
336 updateNoisePower(propInfo);
338 ptrLTENR_PROPAGATIONINFO tempInfo = (ptrLTENR_PROPAGATIONINFO)malloc(
sizeof(LTENR_PROPAGATIONINFO));
342 printf(
"Memory allocation failed.\n");
346 memcpy(tempInfo, propInfo,
sizeof(*propInfo));
348 allocateInfo(tempInfo);
352 tempInfo->selectedBeamId = tempbeamList->beamId;
354 calculateNTN_totalloss(tempInfo);
356 calculateNTNAntennaGain(tempInfo);
358 updateNTN_RxG_T(tempInfo);
361 tempInfo->downlink.SNR_db[layerId] = calculateNTN_SNR(tempInfo, LTENR_BeamForming_Downlink_GetValue(tempInfo, layerId));
363 updateNTNRxPower(tempInfo, layerId);
365 NTN_calculateSINR(tempInfo, layerId);
367 updateNTN_EB_by_N0(tempInfo, layerId);
369 snr = tempInfo->downlink.SNR_db[layerId];
371 NTN_plotUeAssociation(tempInfo, CA_ID, layerId,
false);
376 deepCopyPropagationInfo(propInfo, tempInfo);
379 tempbeamList = tempbeamList->next;
381 NTN_plotUeAssociation(propInfo,CA_ID,layerId,
true);
389static double NTN_calculateCIR_InterferencePower(ptrLTENR_PROPAGATIONINFO propInfo, UINT layerId) {
391 double snr_mw, noise_mw, sinr_mw, interference_mw;
392 noise_mw = DBM_TO_MW(propInfo->downlink.thermalNoise);
393 snr_mw = DBM_TO_MW(propInfo->downlink.SNR_db[layerId]);
394 sinr_mw = DBM_TO_MW(propInfo->downlink.SINR_db[layerId]);
396 interference_mw = noise_mw * (snr_mw / sinr_mw - 1);
398 return MW_TO_DBM(interference_mw);
401void NTN_calculateSINR(ptrLTENR_PROPAGATIONINFO propInfo, UINT layerId) {
403 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
405 if (ntnInfo->interferenceModel == NTN_NONE) {
406 propInfo->downlink.InterferencePower_dbm[layerId] = NEGATIVE_DBM;
407 propInfo->downlink.SINR_db[layerId] = propInfo->downlink.SNR_db[layerId];
409 else if (ntnInfo->interferenceModel == NTN_CIR) {
410 propInfo->downlink.SINR_db[layerId] = NTN_calculateCIR_Sinr(propInfo->downlink.SNR_db[layerId], ntnInfo->carrier_InterferenceRatio);
411 propInfo->downlink.InterferencePower_dbm[layerId] = NTN_calculateCIR_InterferencePower(propInfo,layerId);
414 else if (ntnInfo->interferenceModel == NTN_EXACT_GEOMETRIC_MODEL)
416 double interferencePower = calculateInterferencePower(propInfo, layerId);
417 propInfo->downlink.InterferencePower_dbm[layerId] = interferencePower;
418 propInfo->downlink.SINR_db[layerId] = calculate_sinr((propInfo->downlink.SNR_db[layerId] + propInfo->downlink.thermalNoise), interferencePower, ntnInfo->channelBandwidth);
421 fprintf(stderr,
"Unknown Interference Model");
422 propInfo->downlink.InterferencePower_dbm[layerId] = NEGATIVE_DBM;
423 propInfo->downlink.SINR_db[layerId] = propInfo->downlink.SNR_db[layerId];
428static double Magnitude(NetSim_COORDINATES* p) {
429 return sqrt(p->X * p->X + p->Y * p->Y + p->Z * p->Z);
433static double DotProduct(NetSim_COORDINATES* v1,
const NetSim_COORDINATES* v2) {
434 return v1->X * v2->X + v1->Y * v2->Y + v1->Z * v2->Z;
438void CalculateTheta(ptrLTENR_PROPAGATIONINFO propInfo) {
440 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
442 NetSim_COORDINATES* beam = getBeamCoordinates(propInfo->selectedBeamId);
443 NetSim_COORDINATES* satellite = DEVICE_POSITION(ntnInfo->ntnId);
444 NetSim_COORDINATES* receiver = DEVICE_POSITION(propInfo->ueId);
446 NetSim_COORDINATES v1 = {
447 .X = beam->X - satellite->X,
448 .Y = beam->Y - satellite->Y,
449 .Z = beam->Z - satellite->Z
451 NetSim_COORDINATES v2 = {
452 .X = receiver->X - satellite->X,
453 .Y = receiver->Y - satellite->Y,
454 .Z = receiver->Z - satellite->Z
458 double mag_v1 = Magnitude(&v1);
459 double mag_v2 = Magnitude(&v2);
462 NetSim_COORDINATES v1_norm = {
465 .Z = v1.Z / mag_v1 };
467 NetSim_COORDINATES v2_norm = {
470 .Z = v2.Z / mag_v2 };
473 double dot_product = DotProduct(&v1_norm, &v2_norm);
476 propInfo->theta_rad = acos(dot_product);
480static void NTN_setLOS_state(ptrLTENR_PROPAGATIONINFO propInfo)
482 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
483 double LOS_probability;
484 double r = RANDOM_01;
486 if (ntnInfo->los_mode != NTN_LOS_MODE_USER_DEFINED)
488 double elevationAngle = propInfo->elevationAngle_rad * 180 / M_PI;
489 LOS_probability = NTNget_LOS_probability(ntnInfo->outScenario, elevationAngle);
492 LOS_probability = ntnInfo->los_probability;
494 if (r <= LOS_probability)
495 ntnInfo->state = NTN_STATE_LOS;
497 ntnInfo->state = NTN_STATE_NLOS;
501double calculateNTNshadowloss(ptrLTENR_PROPAGATIONINFO propInfo)
503 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
505 double elevationAngle = propInfo->elevationAngle_rad * 180 / M_PI;
506 NTN_setLOS_state(propInfo);
507 double stdDeviation = get_shadowingSD(ntnInfo->outScenario, ntnInfo->state, ntnInfo->carrierBand, elevationAngle);
508 ntnInfo->standardDeviation = stdDeviation;
509 return NTN_log_normal_distribution(ntnInfo, stdDeviation);
512double calculateNTNclutterloss(ptrLTENR_PROPAGATIONINFO propInfo)
514 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
516 double elevationAngle = propInfo->elevationAngle_rad * 180 / M_PI;
517 NTN_setLOS_state(propInfo);
519 return get_clutterloss(ntnInfo->outScenario, ntnInfo->state, ntnInfo->carrierBand, elevationAngle);
523void updateNTNBandwidth(ptrLTENR_PROPAGATIONINFO propInfo) {
525 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
526 double totalBandwidth = propInfo->bandwidth_MHz;
528 if (ntnInfo->ntnFR_factor != NTN_FREQUENCY_REUSE_FACTOR_1)
530 totalBandwidth -= ntnInfo->guardBand_MHz * (ntnInfo->channelCount - 1);
531 ntnInfo->channelBandwidth = totalBandwidth / ntnInfo->channelCount;
534 ntnInfo->channelBandwidth = totalBandwidth;
538double calculateAntennaGain(
double theta,
double k,
double a)
546 else if (fabs(theta) <= M_PI / 2) {
549 double x = k * a * sin(theta);
550 double besselJ1 = _j1(x);
551 double J1_x = besselJ1 / x;
552 double gain = 4 * pow(J1_x, 2);
553 double maxGain_dbm = MW_TO_DBM(gain);
557 fprintf(stderr,
"Theta not in range");
562double getDistancefromBeam(ptrLTENR_PROPAGATIONINFO propInfo)
564 ptrBeamNode tempbeamList = ntnInfo->beamList;
566 NetSim_COORDINATES* uePos = DEVICE_POSITION(propInfo->ueId);
570 if (propInfo->selectedBeamId == tempbeamList->beamId)
572 double dx = uePos->X - tempbeamList->beamCoord->X;
573 double dy = uePos->Y - tempbeamList->beamCoord->Y;
574 double distance = sqrt(dx * dx + dy * dy);
577 tempbeamList = tempbeamList->next;
582void updateNTN_RxG_T(ptrLTENR_PROPAGATIONINFO propInfo) {
583 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
585 ptrLTENR_UEPHY uePhy = LTENR_UEPHY_GET(propInfo->ueId, propInfo->ueIf);
587 propInfo->rxG_T = uePhy->ueRxAntennaGain - (MW_TO_DBM(NTN_RX_ANTENNA_TEMPERATURE) + ntnInfo->noiseFigure);
591void updateNTN_EB_by_N0(ptrLTENR_PROPAGATIONINFO propInfo, UINT layerId)
593 propInfo->downlink.EB_by_N0[layerId] = DBM_TO_MW(propInfo->downlink.SINR_db[layerId]);
594 propInfo->downlink.spectralEfficiency[layerId] = log2(1 + propInfo->downlink.EB_by_N0[layerId]);
597void updateNTNRxPower(ptrLTENR_PROPAGATIONINFO propInfo, UINT layerId)
599 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
601 ptrLTENR_UEPHY uePhy = LTENR_UEPHY_GET(propInfo->ueId, propInfo->ueIf);
602 propInfo->downlink.rxPower_dbm[layerId] = propInfo->downlink.SNR_db[layerId] + propInfo->downlink.thermalNoise;
605void updateNTN_TxPower(ptrLTENR_PROPAGATIONINFO propInfo, UINT layerId) {
607 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
608 double eirp_dBW = ntnInfo->eirpDensity + MW_TO_DBM(ntnInfo->channelBandwidth);
609 double txPowerDBm = eirp_dBW + 30 - ntnInfo->maxAntennaGain;
610 propInfo->downlink.totaltxpower_dbm = txPowerDBm;
614double calculateInterferencePower(ptrLTENR_PROPAGATIONINFO propInfo, UINT layerId) {
616 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
617 ptrBeamNode tempbeamList = ntnInfo->beamList;
618 double interferenceLinear = 0, snr = 0;
623 if (tempbeamList->beamId == propInfo->selectedBeamId) {
624 currChannelId = tempbeamList->beamChannelId;
627 tempbeamList = tempbeamList->next;
629 ptrLTENR_PROPAGATIONINFO tempInfo = (ptrLTENR_PROPAGATIONINFO)malloc(
sizeof(LTENR_PROPAGATIONINFO));
632 printf(
"Memory allocation failed.\n");
636 memcpy(tempInfo, propInfo,
sizeof(LTENR_PROPAGATIONINFO));
637 allocateInfo(tempInfo);
638 tempbeamList = ntnInfo->beamList;
642 tempInfo->selectedBeamId = tempbeamList->beamId;
644 if (tempbeamList->beamId != propInfo->selectedBeamId && tempbeamList->beamChannelId == currChannelId) {
646 calculateNTN_totalloss(tempInfo);
647 calculateNTNAntennaGain(tempInfo);
649 updateNTN_RxG_T(tempInfo);
652 snr = calculateNTN_SNR(tempInfo, LTENR_BeamForming_Downlink_GetValue(tempInfo, layerId));
653 updateNTNRxPower(tempInfo, layerId);
654 interferenceLinear += DBM_TO_MW(snr + propInfo->downlink.thermalNoise);
656 tempbeamList = tempbeamList->next;
659 propInfo->downlink.InterferencePower_dbm[layerId] = MW_TO_DBM(interferenceLinear);
660 return MW_TO_DBM(interferenceLinear);
663double NTN_calculateCIR_Sinr(
double snr,
double cir)
665 double snr_mw, cir_mw, sinr_mw;
666 snr_mw = CIR_DBM_TO_MW(snr);
667 cir_mw = CIR_DBM_TO_MW(cir);
668 sinr_mw = snr_mw + cir_mw;
669 return CIR_MW_TO_DBM(sinr_mw);
673NetSim_COORDINATES* getBeamCoordinates( UINT
id) {
675 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
677 ptrBeamNode beamList = ntnInfo->beamList;
679 if (beamList->beamId ==
id)
680 return beamList->beamCoord;
681 beamList = beamList->next;
686int getBeamChannelId( UINT
id) {
688 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
689 ptrBeamNode beamList = ntnInfo->beamList;
691 if (beamList->beamId ==
id)
692 return beamList->beamChannelId;
693 beamList = beamList->next;