Skip to content

Commit

Permalink
Merge pull request #7094 from ORNL-AMO/issue-1947
Browse files Browse the repository at this point in the history
Issue 1947: Power Factor Triangle Calc
  • Loading branch information
nbintertech authored Nov 5, 2024
2 parents c28679c + adcdf38 commit 2355dc2
Show file tree
Hide file tree
Showing 27 changed files with 903 additions and 3 deletions.
6 changes: 6 additions & 0 deletions src/app/calculator/standalone.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
ElectricityReductionInput, NaturalGasReductionInput, NaturalGasReductionResult, ElectricityReductionResult,
CompressedAirReductionInput, CompressedAirReductionResult, WaterReductionInput, WaterReductionResult, SteamReductionInput, PipeInsulationReductionInput,
PipeInsulationReductionResult, TankInsulationReductionInput, TankInsulationReductionResult, AirLeakSurveyInput, AirLeakSurveyResult, CompEEM_kWAdjustedInput, SteamReductionOutput, SteamReductionResult,
PowerFactorTriangleModeInputs,
PowerFactorTriangleOutputs,
} from '../shared/models/standalone';
import { Settings } from '../shared/models/settings';
import { ConvertUnitsService } from '../shared/convert-units/convert-units.service';
Expand Down Expand Up @@ -361,4 +363,8 @@ export class StandaloneService {
tankInsulationReduction(inputObj: TankInsulationReductionInput): TankInsulationReductionResult {
return this.calculatorSuiteApiService.tankInsulationReduction(inputObj);
}

powerFactorTriangle(inputObj: PowerFactorTriangleModeInputs): PowerFactorTriangleOutputs {
return this.calculatorSuiteApiService.powerFactorTriangle(inputObj);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
tr:nth-child(odd) {
background-color: lightgray;
}

tr {
font-size: small;
}

.btn-group {
display: block;
text-align: center;
}

.btn-group .btn-sm {
font-size: small !important;
}

.btn-form {
border-radius: 4px !important;
}

.input-group-addon.units.op-hour-addon{
border-left: solid 1px;
border-right: none;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<form>

<div class="form-group">
<label for="mode">Known Inputs</label>
<select id="mode" name="mode" class="form-control" [(ngModel)]="data.mode" (focus)="focusField('mode')"
(change)="calculate()">
<option *ngFor="let mode of modeList" [ngValue]="mode.value">{{mode.name}}</option>
</select>
</div>

<div class="form-group">
<label for="apparentPower">Apparent Power</label>
<div class="input-group calc-addon-group"
*ngIf="data.mode == 1 || data.mode == 2 || data.mode == 3 || data.mode == 4">
<input name="apparentPower" class="form-control" type="number" step="any" [(ngModel)]="data.apparentPower"
id="apparentPower" (input)="calculate()" onfocus="this.select();" (focus)="focusField('apparentPower')">
<span class="input-group-addon units">kVA</span>
</div>
<div class="text-center" *ngIf="data.mode == 5 || data.mode == 6 || data.mode == 7 || data.mode == 8 || data.mode == 9">
<span class="small bold">{{results.apparentPower | number:'1.0-2'}} kVA</span>
</div>
</div>

<div class="form-group">
<label for="realPower">Real Power</label>
<div class="input-group calc-addon-group"
*ngIf="data.mode == 1 || data.mode == 5 || data.mode == 6 || data.mode == 7">
<input name="realPower" class="form-control" type="number" step="any" [(ngModel)]="data.realPower" id="realPower"
(input)="calculate()" onfocus="this.select();" (focus)="focusField('realPower')">
<span class="input-group-addon units">kW</span>
</div>
<div class="text-center" *ngIf="data.mode == 2 || data.mode == 3 || data.mode == 4 || data.mode == 8 || data.mode == 9">
<span class="small bold">{{results.realPower | number:'1.0-2'}} kW</span>
</div>
</div>

<div class="form-group">
<label for="reactivePower">Reactive Power</label>
<div class="input-group calc-addon-group"
*ngIf="data.mode == 2 || data.mode == 5 || data.mode == 8 || data.mode == 9">
<input name="reactivePower" class="form-control" type="number" step="any" [(ngModel)]="data.reactivePower"
id="reactivePower" (input)="calculate()" onfocus="this.select();" (focus)="focusField('reactivePower')">
<span class="input-group-addon units">kVAr</span>
</div>
<div class="text-center" *ngIf="data.mode == 1 || data.mode == 3 || data.mode == 4 || data.mode == 6 || data.mode == 7">
<span class="small bold">{{results.reactivePower | number:'1.0-2'}} kVAr</span>
</div>
</div>

<div class="form-group">
<label for="phaseAngle">Phase Angle</label>
<div class="input-group calc-addon-group" *ngIf="data.mode == 3 || data.mode == 6 || data.mode == 8">
<input name="phaseAngle" class="form-control" type="number" step="any" [(ngModel)]="data.phaseAngle"
id="phaseAngle" (input)="calculate()" onfocus="this.select();" (focus)="focusField('phaseAngle')">
<span class="input-group-addon units">deg</span>
</div>
<div class="text-center" *ngIf="data.mode == 1 || data.mode == 2 || data.mode == 4 || data.mode == 5 || data.mode == 7 || data.mode == 9">
<span class="small bold">{{results.phaseAngle | number:'1.0-2'}} deg</span>
</div>
</div>

<div class="form-group">
<label for="powerFactor">Power Factor</label>
<input *ngIf="data.mode == 4 || data.mode == 7 || data.mode == 9" name="powerFactor" class="form-control"
type="number" step="any" [(ngModel)]="data.powerFactor" id="powerFactor" (input)="calculate()"
onfocus="this.select();" (focus)="focusField('powerFactor')">
<div class="text-center" *ngIf="data.mode == 1 || data.mode == 2 || data.mode == 3 || data.mode == 5 || data.mode == 6 || data.mode == 8">
<span class="small bold">{{results.powerFactor | number:'1.0-2'}}</span>
</div>
</div>


</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { PowerFactorTriangleFormComponent } from './power-factor-triangle-form.component';

describe('PowerFactorTriangleFormComponent', () => {
let component: PowerFactorTriangleFormComponent;
let fixture: ComponentFixture<PowerFactorTriangleFormComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [PowerFactorTriangleFormComponent]
})
.compileComponents();

fixture = TestBed.createComponent(PowerFactorTriangleFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { PowerFactorTriangleInputs, PowerFactorTriangleOutputs } from '../../../../shared/models/standalone';

@Component({
selector: 'app-power-factor-triangle-form',
templateUrl: './power-factor-triangle-form.component.html',
styleUrls: ['./power-factor-triangle-form.component.css']
})
export class PowerFactorTriangleFormComponent implements OnInit {

@Input()
data: PowerFactorTriangleInputs;
@Input()
results: PowerFactorTriangleOutputs;
@Output('changeField')
changeField = new EventEmitter<string>();

@Output('emitCalculate')
emitCalculate = new EventEmitter<PowerFactorTriangleInputs>();

modeList: Array<{ value: number, name: string }> = [
{ value: 1, name: 'Apparent & Real' },
{ value: 2, name: 'Apparent & Reactive' },
{ value: 3, name: 'Apparent & Phase Angle' },
{ value: 4, name: 'Apparent & Power Factor' },
{ value: 5, name: 'Real & Reactive' },
{ value: 6, name: 'Real & Phase Angle' },
{ value: 7, name: 'Real & Power Factor' },
{ value: 8, name: 'Reactive & Phase Angle' },
{ value: 9, name: 'Reactive & Power Factor' },
];

constructor() { }

ngOnInit() {
}

calculate() {
if (this.data.apparentPower != null && this.data.realPower != null && this.data.reactivePower != null && this.data.phaseAngle != null && this.data.powerFactor != null) {
this.emitCalculate.emit(this.data);
}
}

focusField(str: string) {
this.changeField.emit(str);
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<div class="p-4 pt-2 d-flex flex-column help-info">
<h5>
Power Factor Triangle Help
<br>
<small class="text-muted">Power factor is the ratio of real (useful) power to the apparent power that your utility
must supply. Low power factor means the utility must extra power to your facility. The main cause of low power
factor in industrial facilities is inductive loads from partially loaded motors. You can be penalized for having a
low power factor, significantly increasing your energy costs. Correcting your power factor can eliminate these
penalties, increase load capability in existing circuits, and reduce power system losses.
<hr>
The purpose of Power Factor Correction is to raise your facility’s power factor closer to 1.0 by installing
capacitance to counterbalance inductive loads. Many utilities charge a ‘power factor fee’ for having a power
factor below a minimum level (often 0.95).
<hr>
This calculator can be used to calculate different aspects of the power factor triangle and explore how adjusting
your power factor affects delivered power.

</small>
</h5>
<hr class="my-1 hr-spacer">

<div class="my-2" *ngIf="currentField == 'mode'">
<h6>
Known Inputs
<br>
<small class="text-muted">
Which combination of power factor parameters do you have data for?
<hr>
</small>
</h6>
</div>


<div class="my-2" *ngIf="currentField == 'apparentPower'">
<h6>
Apparent Power
<br>
<small class="text-muted">
The total amount of AC power delivered by the utility to your facility. The magnitude of apparent power can be
found with the power factor triangle and the Pythagorean theorem. Apparent power is measured in kilovolt-ampere
(kVA).
<hr>
</small>
</h6>
</div>

<div class="my-2" *ngIf="currentField == 'realPower'">
<h6>
Real Power
<br>
<small class="text-muted">
The component of delivered AC power that does actual work. Real power is measured in kilowatts (kW).
<hr>
</small>
</h6>
</div>

<div class="my-2" *ngIf="currentField == 'reactivePower'">
<h6>
Reactive Power
<br>
<small class="text-muted">
The component of delivered AC power that does no work but is required to energize reactive loads like capacitors
and inductors. Reactive power is measured in reactive kilovolt-ampere (kVAr).
<hr>
</small>
</h6>
</div>


<div class="my-2" *ngIf="currentField == 'phaseAngle'">
<h6>
Phase Angle
<br>
<small class="text-muted">
The angle between the current and voltage in an AC circuit. Phase angle can also be visualized as the angle
between real and apparent power in the power factor triangle.
</small>
</h6>
</div>

<div class="my-2" *ngIf="currentField == 'powerFactor'">
<h6>
Power Factor
<br>
<small class="text-muted">
The ratio between real power that does work and the actual apparent power delivered by the utility. A low power
factor means that your utility must supply a lot of extra energy to your facility to do the same amount of real
work. Power factor is also the cosine of the phase angle.
<hr>
</small>
</h6>
</div>


</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { PowerFactorTriangleHelpComponent } from './power-factor-triangle-help.component';

describe('PowerFactorTriangleHelpComponent', () => {
let component: PowerFactorTriangleHelpComponent;
let fixture: ComponentFixture<PowerFactorTriangleHelpComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [PowerFactorTriangleHelpComponent]
})
.compileComponents();

fixture = TestBed.createComponent(PowerFactorTriangleHelpComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Component, Input } from '@angular/core';

@Component({
selector: 'app-power-factor-triangle-help',
templateUrl: './power-factor-triangle-help.component.html',
styleUrls: ['./power-factor-triangle-help.component.css']
})
export class PowerFactorTriangleHelpComponent {
@Input()
currentField: string;
constructor() { }

ngOnInit() {
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
td {
font-size: small;
}

td {
font-size: small;
border-right: solid 1px darkgray;
border-left: solid 1px darkgray;
padding: 3px;
}

tbody {
box-shadow: 0 4px 8px 0 grey
}

tr {
font-size: small;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div #powerFactorTiangle></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { PowerFactorTriangleResultsComponent } from './power-factor-triangle-results.component';

describe('PowerFactorTriangleResultsComponent', () => {
let component: PowerFactorTriangleResultsComponent;
let fixture: ComponentFixture<PowerFactorTriangleResultsComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [PowerFactorTriangleResultsComponent]
})
.compileComponents();

fixture = TestBed.createComponent(PowerFactorTriangleResultsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Loading

0 comments on commit 2355dc2

Please sign in to comment.