Blog Entry © Friday, May 23, 2025, NASA Geopotential Altitude and the Variation of the Gravitational Acceleration by James Pate Williams, Jr., BA, BS, Master of Software Engineering, PhD Computer Science

More source code is available upon request.
Reference: 19770009539.pdf
Win32 C/C++ application output to a Win32 window:
H Z1 Z2 Z3 g
80000 79005.7 79005.7 79005.7 9.56735
80500 79493.3 79493.3 79493.3 9.56590
81000 79980.9 79980.9 79980.9 9.56446
81500 80468.3 80468.3 80468.3 9.56301
82000 80955.7 80955.7 80955.7 9.56156
82500 81443.0 81443.0 81443.0 9.56011
83000 81930.2 81930.2 81930.2 9.55867
83500 82417.4 82417.4 82417.4 9.55722
84000 82904.5 82904.5 82904.5 9.55577
84500 83391.5 83391.5 83391.5 9.55433
85000 83878.4 83878.4 83878.4 9.55288
85500 84365.3 84365.3 84365.3 9.55144
H Geopotential Altitude
Z1 Geopotential Gauss-Legendre 128 Steps
Z2 Geopotential Simpson's Rule 256 Steps
Z3 Geopotential Trapezoidal Rule 512 Steps
g gravitational acceleration in m/s/s
https://ntrs.nasa.gov/api/citations/19770009539/downloads/19770009539.pdf
See Table 8. Page 9
// NASAGeopotentialAltitude.cpp : Defines the entry point for the application.
// Copyright (c) Friday, May 23, 2025 by James Pate Williams, Jr.
// BA, BS, MSWE, PhD All Applicable Rights Reserved

#include "stdafx.h"
#include "GeopotentialAltitude.h"
#include "Integration1d.h"
#include "NASAGeopotentialAltitude.h"
#include <math.h>
#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include <vector>
using namespace std;

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name

// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Place code here.
	MSG msg;
	HACCEL hAccelTable;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_NASAGEOPOTENTIALALTITUDE, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_NASAGEOPOTENTIALALTITUDE));

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}

//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_NASAGEOPOTENTIALALTITUDE));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_NASAGEOPOTENTIALALTITUDE);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_CREATE   - creates a multiple line edit control
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//

#define ID_EDITCHILD 100
char asciiData[16384];
char asciiLine[16384];
TCHAR textData[16384];

void ConvertCharToTChar(const char* charArray, TCHAR* tcharArray, size_t tcharSize) {
#ifdef _UNICODE
	MultiByteToWideChar(CP_ACP, 0, charArray, -1, tcharArray, (int)tcharSize);
#else
    strncpy(tcharArray, charArray, tcharSize - 1);
    tcharArray[tcharSize - 1] = '\0'; // Ensure null-termination
#endif
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	static HWND hwndEdit;
	static double zArray[] = {
		80000, 80500, 81000, 81500, 82000, 82500,
		83000, 83500, 84000, 84500, 85000, 85500 };
	static vector<double> z(12);
	static vector<double> potential1(12);
	static vector<double> potential2(12);
	static vector<double> potential3(12);
	static vector<double> potential4(12);
	size_t numberPoints = z.size();

	for (size_t i = 0; i < z.size(); i++)
	{
		z[i] = zArray[i];
	}

	switch (message)
	{
	case WM_CREATE:
	GeopotentialAltitude::GaussianLegendre(
		numberPoints, z, potential1);
	GeopotentialAltitude::SimpsonsRule(
		numberPoints, z, potential2);
	GeopotentialAltitude::TrapezoidalRule(
		numberPoints, z, potential3);

	strcpy_s(asciiData, 16384, "H\tZ1\tZ2\tZ3\tg\r\n");

	for (size_t i = 0; i < z.size(); i++)
	{
		double zi = z[i];
		double p1 = potential1[i];
		double p2 = potential2[i];
		double p3 = potential3[i];
		double g = g0 * pow(r0 / (r0 + p1), 2.0);

		sprintf_s(
			asciiLine, 16384,
			"%5.0lf\t%5.1lf\t%5.1lf\t%5.1lf\t%7.5lf\r\n",
			zi, p1, p2, p3, g);
		strcat_s(asciiData, 16384, asciiLine);
	}

	strcat_s(asciiData, "H Geopotential Altitude\r\n");
	strcat_s(asciiData, "Z1 Geopotential Gauss-Legendre 128 Steps\r\n");
	strcat_s(asciiData, "Z2 Geopotential Simpson's Rule 256 Steps\r\n");
	strcat_s(asciiData, "Z3 Geopotential Trapezoidal Rule 512 Steps\r\n");
	strcat_s(asciiData, "g gravitational acceleration in m/s/s\r\n");
	strcat_s(asciiData, "https://ntrs.nasa.gov/api/citations/19770009539/downloads/19770009539.pdf\r\n");
	strcat_s(asciiData, "See Table 8. Page 9\r\n");

	ConvertCharToTChar(asciiData, textData, sizeof(textData));

	// https://learn.microsoft.com/en-us/windows/win32/controls/use-a-multiline-edit-control

	hwndEdit = CreateWindowEx(
		0, L"EDIT",   // predefined class 
        NULL,         // no window title 
        WS_CHILD | WS_VISIBLE | WS_VSCROLL | 
        ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 
        0, 0, 0, 0,   // set size in WM_SIZE message 
        hWnd,         // parent window 
        (HMENU) ID_EDITCHILD,   // edit control ID 
		hInst,
        /*(HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE),*/ 
		NULL);        // pointer not needed 
    // Add text to the window. 
	SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM) textData); 
    return 0; 
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: Add any drawing code here...
		EndPaint(hWnd, &ps);
		break;
	case WM_SIZE: 
            // Make the edit control the size of the window's client area. 
		MoveWindow(hwndEdit, 
			0, 0,                  // starting x- and y-coordinates 
            LOWORD(lParam),        // width of client area 
            HIWORD(lParam),        // height of client area 
            TRUE);                 // repaint window 
        return 0; 
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}

Revised Helium Ground-State Total Energy Computation (c) Sunday, March 23, 2025, by James Pate Williams, Jr.

Blog Entry, Thursday, March 20, 2025, Another Helium Variational Calculation by James Pate Williams, Jr.

Solution of the Fermi-Thomas Potential Energy Equation for Zero Temperature and without Exchange by James Pate Williams, Jr.

Reproduction and Extension of Metropolis Among Others Results in Their 1953 Technical Report (c) February 22, 2025, by James Pate Williams, Jr.

Blog Entry (c) Sunday, October 20, 2024, by James Pate Williams, Jr. New and Improved Ab Initio Quantum Chemistry Computations Using the Simple Two Electron Systems: The Helium-Hydrogen Cation and the Hydrogen Molecule

I modified my translation of a FORTRAN program mentioned in a couple of my recent blog entries. The hybrid C/C++ source code is 1,291 lines. I find the basis set of Gaussian Type 1s Orbitals (GTO-NG) using my evolutionary hill-climber, where the GTO1s-NGs curve fit a Slater Type 1s Orbital (STO1s-NG), where N = 4 and 5 in the cation case and N = 4 in the molecule calculation. The percent errors in both cases are considerably less than 1%.

Blog Entry (c) Saturday, October 19, 2024, New Ab Initio Calculations to Determine the Ground State Energies of the Helium-Hydrogen Cation and the Hydrogen Molecule

Using my STO-4G curve fit for N = 4 basis Gaussian type 1s orbitals I was able to get better results than found using the N = 3 basis wavefunctions in the graduate-level textbook Modern Quantum Chemistry Introduction to Advanced Electronic Structure Theory by Attila Szabo and Neil S. Ostlund. My recreation for N = 3 discovered -2.97867 atomic units ground state energy for the helium-hydrogen ion and -1.11651 atomic units for the hydrogen molecule using the textbook’s basis wavefunctions. The percentage errors were 3.98002% and 4.15928% respectively. My STO-4G basis wavefunctions found a ground state energy for the helium-hydrogen ion of -2.94937 atomic units and for the hydrogen molecule -1.14344 atomic units, which have percentage errors of 0.98349% and 2.86607% respectively.

Blog Entry (c) Friday, October 18, 2024, by James Pate Williams, Jr. Ab Initio Quantum Chemical Calculation

On Wednesday, October 16, 2024, I bought an Amazon Kindle book named “Modern Quantum Chemistry: Introduction to Advanced Electronic Structure Theory” by Attila Szabo and Neil S. Ostlund. It cost me $10.69 which is a real bargain. In Appendix B there is a listing for a FORTRAN program to perform an ab initio Hartree-Fock Self Consistent Field calculation for a two-electron heteronuclear molecule namely the helium-hydrogen cation. I successfully translated the program from FORTRAN to C++. I had to remember that FORTRAN stores matrices in column major order and C/C++ stores matrices in row major order. I took the transposes of two FORTRAN COMMON matrices to get the correct C++ storage. The authors of the book did an extensive treatment of the test calculation. The application is only 823 lines of monolithic C++ source code. I used FORTRAN like array indexing starting at 1 instead of the C initial beginning index of 0. I think I will try to get in touch with the authors to get permission to post the source code and results on my blog. 

P. S. I got permission from Dover Books to publish my source code and results. I think I will reconsider posting the C++ source code. The actual ground state energy of the cation is -2.97867. My calculation and the book’s computation are in percentage errors of about 4%. The book’s value is a little closer to the exact value than my result. The book calculation was done in FORTRAN double precision on a Digital Equipment Corporation PDP-10 minicomputer. My recreation of the book’s endeavor was executed on an Intel Itanium Core 7 and Windows 10 Professional machine using Win32 C++. The C++ compiler was from Microsoft Visual Studio 2019 Community Version.

Note I added a calculation for a homonuclear molecule, namely, the hydrogen diatomic molecule.

Blog Entry © Thursday, October 3, 2024, by James Pate Williams, Jr. A Mixture of Numerical Analysis and General Relativity Physics