Monday, April 7, 2025

Finally in Bharat, the interviewers are asking - What have you built and NOT where did you graduate from...

 Yes — and finally, yes in a real way.

Indian software companies are definitely shifting focus from degrees to skills, especially over the last 3–5 years. While a formal degree still opens some doors, real-world skills, projects, and portfolios are becoming the real currency.

For developers in Bharat - open source and github/gitlab are gradually becoming the resume of a candidate.

Nobody wants to know about the degree - it has become obsolete.

Companies like Google, Apple, and Tesla dropped mandatory degree requirements. Indian firms (especially startups and product-based companies) are following suit.

Who’s leading the way?

  • Startups: Razorpay, Zerodha, CRED, Postman, etc.

  • Mid-size firms: Zoho, TCS Digital, Infosys' HackWithInfy route

  • Big players (slowly but surely): Infosys, Wipro, TCS now allow non-engineers into tech roles via skill tracks.

For the students of Bengal - who flock to Kolkata for higher studies - please remember - your strength in English speaking skills and vocabulary won't give you a good software job - rather your software skills will keep you hot in the job market.

This is exactly what I said many years ago...

Enjoy my viewpoint as a software trainer.



The reverse osmosis - the Factory Design Pattern written and executed using C++ and AngelScript...

I had always believed that knowledge flowed in one direction—from the old to the young, from teacher to student, from father to son. And for most of Ridit's childhood, that seemed true. I had introduced him to Java, C++, even helped him debug his first Python script. To me, guiding my son through the world of code was like watching seeds grow into a tree.

But trees have roots. And sometimes, the water flows up.

One sultry afternoon, I sat at my desk, thinking about a simple script engine especially made for C++. I have already tried with Python.Boost and SWIG. But I wanted to get something which is especially made for C++.

“I wish I could just write the logic in a script file and have the engine read it on the fly,” I muttered.

Ridit, my son, now in class IX, overheard me while lounging nearby with his laptop. He casually said, “Why don’t you try AngelScript?”

I looked up. “What’s that?”

“It’s a scripting language for games and simulations. Super fast, safe, and looks almost like C++. I used it to modify that open-source shooter I play—remember the one with voxel maps?”

I was intrigued but skeptical. “Never heard of it. You sure it can interface with my C++ code cleanly?”

Ridit opened his laptop and pulled up a project. “Here, look. You register your C++ objects like this, and then scripts can call them directly. No weird glue code. It's pretty smart.”

I leaned in, stunned at how elegant the integration looked. There it was—my solution, sitting quietly in my son's world this whole time.

By midnight, I had AngelScript embedded. My singleton Factory class was being called from a .as file, creating Biscuit and Chocolate objects like magic. All without a single recompile.

As we sat there, I finally spoke, eyes twinkling:

“You know, reverse osmosis usually means filtering the purest water against pressure. Today, I think the wisdom flowed backward—from son to father, against tradition—but damn, was it pure.”

Ridit grinned. “Guess I’m your tech support now.”

From that day, whenever I hit a wall, I'd first ask myself:

“What would my son Ridit do?”

So.... here we go...

The source code of the Factory Design Pattern in C++ and AngelScript...

/*

* Factory.h

*

* Created on: Mar 10, 2021

* Author: som

*/


#ifndef FACTORY_H_

#define FACTORY_H_


#include <iostream>

#include <string>


#include "Biscuit.h"

#include "Chocolate.h"


using namespace std;


class Factory{

public:

static Factory* instance;

static Factory* getInstance();


Food* makeFood(const string& type);


private:

Factory(){}


// Delete copy constructor & assignment operator (Singleton pattern)

Factory(const Factory&) = delete;

Factory& operator=(const Factory&) = delete;

};

//Factory* Factory:: instance = NULL;



#endif /* FACTORY_H_ */





/*

* Factory.cpp

*

* Created on: Jan 30, 2025

* Author: som

*/

#include "Factory.h"


Factory* Factory::instance = NULL;


Factory* Factory:: getInstance(){

if(Factory::instance == NULL){

Factory::instance = new Factory();

}

return Factory::instance;

}


Food* Factory::makeFood(const string& type){

if(type.compare("bi") == 0){

return new Biscuit();

}

if(type.compare("ch") == 0){

return new Chocolate();

}


std::cerr << "Unknown food type: " << type << std::endl;


return nullptr;

}



/*

* Food.h

*

* Created on: Mar 10, 2021

* Author: som

*/


#ifndef FOOD_H_

#define FOOD_H_

#include <string>


using namespace std;


class Food {

public:

virtual string getName() = 0;


virtual ~Food(){


}

};



#endif /* FOOD_H_ */



/*

* Biscuit.h

*

* Created on: Mar 10, 2021

* Author: som

*/


#ifndef BISCUIT_H_

#define BISCUIT_H_


#include "Food.h"


class Biscuit: public Food {

public:

Biscuit();

string getName();

~Biscuit();

};


#endif /* BISCUIT_H_ */




/*

* Biscuit.cpp

*

* Created on: Mar 10, 2021

* Author: som

*/

#include <iostream>

#include "Biscuit.h"

using namespace std;



Biscuit::Biscuit() {

// TODO Auto-generated constructor stub

cout<<"Biscuit is made..."<<endl;


}


Biscuit::~Biscuit(){}



string Biscuit::getName(){

return "It's a Biscuit";

}



/*

* Chocolate.h

*

* Created on: Mar 10, 2021

* Author: som

*/


#ifndef CHOCOLATE_H_

#define CHOCOLATE_H_


#include <iostream>

#include "Food.h"


class Chocolate: public Food {

public:

Chocolate();

virtual ~Chocolate();

string getName();

};



#endif /* CHOCOLATE_H_ */




/*

* Chocolate.cpp

*

* Created on: Mar 10, 2021

* Author: som

*/


#include "Chocolate.h"



Chocolate::Chocolate() {

// TODO Auto-generated constructor stub

cout<<"Chocolate is made..."<<endl;


}


Chocolate::~Chocolate() {

// TODO Auto-generated destructor stub

}


string Chocolate::getName(){

return "It's a Chocolate";

}




Test.as


void main() {

Factory@ factory = getFactory();

if (factory is null) {

print("Factory is null!");

return;

}


Food@ item1 = factory.makeFood("ch");

if (item1 is null) {

print("item1 is null!");

} else {

print(item1.getName());

}


Food@ item2 = factory.makeFood("bi");

if (item2 is null) {

print("item2 is null!");

} else {

print(item2.getName());

}

}



//============================================================================

// Name : FactoryPattern.cpp

// Author : Som

// Version :

// Copyright : som-itsolutions

// Description : Hello World in C++, Ansi-style

//============================================================================



#include <iostream>

#include <angelscript.h>

#include <scriptstdstring.h>

#include <scriptbuilder.h>


#include "Factory.h"


using namespace std;


void print(const std::string &msg) {

std::cout << msg << std::endl;

}


int RegisterWithAngelScript(asIScriptEngine* engine) {

// Register std::string

//RegisterStdString(engine);


// Register base class


int r;


RegisterStdString(engine);


r = engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_CDECL);

if (r < 0) { std::cerr << "Failed to register print()\n"; return -1; }


r = engine->RegisterObjectType("Food", 0, asOBJ_REF | asOBJ_NOCOUNT);

if (r < 0) { std::cerr << "Failed to register Food\n"; return -1; }

engine->RegisterObjectMethod("Food", "string getName()", asMETHOD(Food, getName), asCALL_THISCALL);

// Register Factory

engine->RegisterObjectType("Factory", 0, asOBJ_REF | asOBJ_NOCOUNT);

engine->RegisterGlobalFunction("Factory@ getFactory()", asFUNCTION(Factory::getInstance), asCALL_CDECL);

engine->RegisterObjectMethod("Factory", "Food@ makeFood(const string &in)", asMETHOD(Factory, makeFood), asCALL_THISCALL);


return 0;

}


int main() {


//int r;


asIScriptEngine* engine = asCreateScriptEngine();

if (!engine) {

std::cerr << "Failed to create script engine" << std::endl;

return -1;

}

//RegisterStdString(engine);

int ret = RegisterWithAngelScript(engine);


if (ret <0 ){

std::cerr << "Failed to register" << std::endl;

return -1;

}


CScriptBuilder builder;

builder.StartNewModule(engine, "MyModule");

builder.AddSectionFromFile("src/test.as");

int retValofBuilder = builder.BuildModule();


if (retValofBuilder < 0) {

std::cerr << "Script build failed!" << std::endl;

return -1;

}


asIScriptModule *mod = engine->GetModule("MyModule");

asIScriptFunction *func = mod->GetFunctionByDecl("void main()");

asIScriptContext *ctx = engine->CreateContext();


ctx->Prepare(func);

int r = ctx->Execute();

if (r != asEXECUTION_FINISHED) {

if (r == asEXECUTION_EXCEPTION) {

std::cerr << "⚠️ Script Exception: " << ctx->GetExceptionString() << std::endl;

const asIScriptFunction *func = ctx->GetExceptionFunction();

std::cerr << "⚙️ Function: " << func->GetDeclaration() << std::endl;

std::cerr << "📍 Line: " << ctx->GetExceptionLineNumber() << std::endl;

} else if (r == asEXECUTION_ABORTED) {

std::cerr << "❌ Script was aborted." << std::endl;

} else if (r == asEXECUTION_SUSPENDED) {

std::cerr << "⏸ Script was suspended." << std::endl;

} else {

std::cerr << "❌ Script execution failed with code: " << r << std::endl;

}

}

ctx->Release();

engine->ShutDownAndRelease();

return 0;

}



Tuesday, March 11, 2025

The curious engineer is still thriving in me - checking the veracity of the continuity equation in computational fluid dynamics...

 It was early in the morning. Everywhere there was a pin-drop silence. After the regular morning exercise, I turned on my laptop. Today's plan was to verify the continuity equation of computational fluid dynamics. For noncompressible fluid, the continuity equation can be mathematically written as U=0. It's the conservation of mass in fluid simulation. Whatever goes into a volume has to come out - no creation, no destruction, just pure, seamless flow.

The paraFoam is good for visualizing the cavity example of the Tutorial that comes with openFoam. As I am new to using ParaView, i preferred raw data exported to a CSV file.

So I created the following Python script.

from paraview.simple import *

# Load the OpenFOAM case

foamCase = OpenFOAMReader(FileName="cavity.OpenFOAM")

foamCase.MeshRegions = ['internalMesh']

foamCase.CellArrays = ['U'] # Ensure velocity field is loaded


# Apply the new Gradient filter

gradFilter = Gradient(Input=foamCase)

gradFilter.ScalarArray = ['POINTS', 'U'] # Compute gradient of velocity U


# Show the gradient field in ParaView

gradDisplay = Show(gradFilter)

ColorBy(gradDisplay, ('POINTS', 'Gradient'))


# Apply a color map for better visualization

glyph = Glyph(Input=gradFilter, GlyphType='Arrow')

glyph.ScaleFactor = 0.01 # Adjust the size

Show(glyph)

Render()

# Optional: Save visualization as an image

SaveScreenshot("grad_U_visualization.png")

writer = CreateWriter("gradU_data.csv", gradFilter)

writer.UpdatePipeline()

Now the time is to test the veracity of the continuity equation.

So, another Python script as follows.

import pandas as pd
import matplotlib.pyplot as plt

# Load CSV file
df = pd.read_csv("/home/som/OpenFOAM/som-dev/run/cavity/cavity/gradU_data.csv")

# Compute divergence of U (sum of diagonal terms of gradient matrix)
df["divU"] = df["Gradient:0"] + df["Gradient:4"] + df["Gradient:8"]

# Plot divergence
plt.plot(df["Points:0"], df["divU"], marker="o", linestyle="-", label="∇·U")
plt.axhline(0, color='r', linestyle="--", label="Zero Line")
plt.xlabel("X Position")
plt.ylabel("Divergence of Velocity (∇·U)")
plt.title("Verification of Continuity Equation (∇·U)")
plt.legend()
plt.grid()
plt.show()

# Check if max deviation from zero is small
print("Max |∇·U| =", df["divU"].abs().max())



A little explanation for the code 
df["divU"] = df["Gradient:0"] + df["Gradient:4"] + df["Gradient:8"]
This is important because we must take the diagonal values of a 
3X3 matrix to verify the continuity equation.
Everything was looking fine except near the lid. The value was high. 

Max |∇·U| = 100.0.

The culprits were located near the moving lid and the corner regions of the cavity. This made sense—corners were prone to numerical singularities due to discontinuities in the velocity gradient.

Not to my surprise. But i wanted to verify using a histogram image.

So added the following python script.

plt.hist(df["divU"], bins=50)
plt.xlabel("∇·U values")
plt.ylabel("Frequency")
plt.title("Distribution of divergence (∇·U)")
plt.show()

And voila.

Most of the values are almost 0.

The scientist in me became happy to contribute to the learning community.

Happy learning...

Here's the simulation exported from ParaView...



That's it for today.

Reclaiming #WhoWeAre...

Friday, February 21, 2025

My first day encounter with KDevelop - simple yet powerful...


It was a calm afternoon in Kolkata. Yesterday it rained. The weather was muggy. There was silence everywhere.... only a few crows were making sound.

Before going to school, my son Ridit suggested that we must give a try to KDevelop for our C++ projects. So I installed the KDevelop using the apt command.

As I am planning to do a deep dive in openFoam source code, the first thing I did was to navigate to the openFoam source directory and opened the project in KDevelop.

I then built it...

And voila.... my dev environment is ready.

As I shut my laptop, I realized I found a new favorite IDE—one that struck a perfect balance between simplicity and power.

Thursday, February 20, 2025

Computational Fluid Dynamics (CFD) & Fluid Simulation in ISRO and DRDO - my exploration continues...

My exploration continues...

Watch...



Both ISRO (Indian Space Research Organisation) and DRDO (Defence Research and Development Organisation) heavily rely on CFD (Computational Fluid Dynamics) and fluid simulations for aerospace, defense, and hypersonic vehicle design. They use high-performance computing (HPC), indigenous CFD solvers, and experimental validation for these applications.

1️⃣ ISRO: CFD Applications in Space Science 🚀

ISRO uses CFD simulations in various projects related to rocketry, re-entry vehicles, aerodynamics, and propulsion systems.

✅ Key CFD Applications in ISRO

  1. Rocket Aerodynamics & Re-entry Simulation

    • CFD is used to analyze airflow, pressure, and heating effects on launch vehicles like PSLV, GSLV, and LVM3.
    • Re-entry vehicles (Gaganyaan Crew Module) undergo hypersonic flow simulations to predict shock waves and thermal loads.
  2. Propulsion & Combustion Analysis

    • CFD helps in designing cryogenic, semi-cryogenic, and solid rocket engines.
    • Combustion chamber simulations predict fuel mixing efficiency and pressure variations in engines like Vikas and CE-20.
  3. Hypersonic Vehicle Simulations

    • Reusable Launch Vehicles (RLV) and Scramjets require CFD to analyze Mach 5+ speeds.
    • ISRO’s Scramjet Engine Test Flight (ATV) used CFD to predict shock interaction and fuel-air mixing.
  4. Satellite Thermal & Fluid Analysis

    • Thermal control systems use CFD to analyze fluid movement inside heat pipes.
    • Cryogenic fuel behavior inside tanks is simulated for fuel sloshing and vapor formation.

🖥️ Software & Tools Used in ISRO

  • OpenFOAM & Fluent – Used for general CFD analysis.
  • ISRO’s In-house CFD Solvers – Developed for hypersonic flow and propulsion studies.
  • ParaView & Tecplot – Used for visualizing simulation results.
  • HPC Clusters"SAGA" supercomputer is used for large-scale simulations.

💡 Example: ISRO used CFD to analyze the Gaganyaan Crew Module’s re-entry heating, ensuring astronauts survive high temperatures.


2️⃣ DRDO: CFD in Defense & Hypersonic Research 🛡️

DRDO (Defence Research and Development Organisation) applies fluid simulations in missiles, hypersonic systems, naval hydrodynamics, and UAVs.

✅ Key CFD Applications in DRDO

  1. Missile Aerodynamics & Guidance

    • CFD is used to simulate airflows around missiles like Agni, BrahMos, and Astra.
    • Studies include drag reduction, shock waves, and stability analysis.
  2. Hypersonic Weapons & Scramjet Engines

    • Hypersonic Technology Demonstrator Vehicle (HSTDV) used CFD for shockwave & heat analysis.
    • Scramjet CFD simulations analyze airflow and combustion at Mach 6+ speeds.
  3. Naval Hydrodynamics & Submarine CFD

    • DRDO’s naval research (NSTL, Visakhapatnam) uses CFD for submarine stealth, torpedo movement, and cavitation studies.
    • Underwater explosions and sonar signal behavior are simulated.
  4. Tank & Aircraft Aerodynamics

    • Arjun & T-90 tanks use CFD for dust flow, heat dissipation, and armor cooling.
    • Tejas Fighter Jet & AMCA (Advanced Medium Combat Aircraft) use CFD for stealth & aerodynamics optimization.

🖥️ Software & Tools Used in DRDO

  • ANSYS Fluent & CFX – Used for general missile & aerodynamics analysis.
  • OpenFOAM & SU2 – Open-source solvers for research & academic collaboration.
  • DRDO In-house CFD Codes – Special codes for hypersonic & naval simulations.
  • HPC Supercomputers"Dhruva" & "Aditya" supercomputers for high-speed calculations.

💡 Example: BrahMos missile’s CFD simulations optimized supersonic airflow and shockwave interaction, improving missile performance.


3️⃣ Research Centers & Universities Involved

Many IITs, IISc, and DRDO labs collaborate on CFD-based aerospace & defense research:

🔹 ISRO’s VSSC (Vikram Sarabhai Space Centre) – CFD for rockets & re-entry.
🔹 DRDO’s ADA (Aeronautical Development Agency) – CFD for Tejas & AMCA jets.
🔹 DRDL (Defence Research & Development Laboratory) – Missile CFD research.
🔹 NSTL (Naval Science & Technological Laboratory) – Naval hydrodynamics & submarine CFD.
🔹 IISc Bangalore & IIT Madras – Hypersonics & scramjet simulations using OpenFOAM.


Conclusion

CFD is a critical technology in ISRO & DRDO for aerospace and defense applications.
ISRO uses CFD for rockets, re-entry vehicles, combustion, and thermal analysis.
DRDO applies CFD in missiles, hypersonic weapons, submarines, and UAVs.
India has strong research in CFD, with IITs, IISc, and DRDO labs leading innovation.

Friday, January 31, 2025

Connecting C++ to Python using Boost.Python...


Gyan.... Knowledge...Wisdom... my wife Reema reciting her own poem...

Many modern C++ applications provide a Python interface because it combines performance (C++) with ease of use (Python). Here’s why this trend has become so popular:

✔ It allows rapid prototyping.
✔ It combines speed (C++) with flexibility (Python).
✔ Python is popular in AI, ML, and scientific computing.
✔ Users can extend software via Python scripting.

 Boost.Python is a powerful library that enables seamless integration between C++ and Python. It allows C++ functions and classes to be exposed to Python, enabling direct interaction between the two languages.

As I was playing around with Boost.Python, I made my existing Factory Pattern project written in C++ to expose itself to the python using Boost.Python library.

The most important part is the following lines of code. This is kind of self explanatory - how we expose the C++ classes and methods to Python code.

// Expose Singleton Factory to Python

BOOST_PYTHON_MODULE(FactoryPattern) {

using namespace boost::python;


class_<Food, boost::noncopyable>("Food", no_init)

.def("getName", pure_virtual(&Food::getName));


class_<Biscuit, bases<Food>>("Biscuit")

.def("getName", &Biscuit::getName); // Ensure Biscuit has getName


class_<Chocolate, bases<Food>>("Chocolate")

.def("getName", &Chocolate::getName); // Ensure Chocolate has getName


class_<Factory, boost::noncopyable>("Factory", no_init)

.def("getInstance", &Factory::getInstance, return_value_policy<reference_existing_object>())

.staticmethod("getInstance")

.def("makeFood", &Factory::makeFood, return_value_policy<manage_new_object>());

}

Here's the complete source code of the C++ Factory Pattern... We will have to make a shared object (so) from this C++ project.

/*

* Food.h

*

* Created on: Mar 10, 2021

* Author: som

*/


#ifndef FOOD_H_

#define FOOD_H_

#include <string>


using namespace std;


class Food {

public:

virtual string getName() = 0;


virtual ~Food(){


}

};



#endif /* FOOD_H_ */




/*

* Chocolate.h

*

* Created on: Mar 10, 2021

* Author: som

*/


#ifndef CHOCOLATE_H_

#define CHOCOLATE_H_


#include <iostream>

#include "Food.h"


class Chocolate: public Food {

public:

Chocolate();

virtual ~Chocolate();

string getName();

};



#endif /* CHOCOLATE_H_ */




/*

* Chocolate.cpp

*

* Created on: Mar 10, 2021

* Author: som

*/


#include "Chocolate.h"



Chocolate::Chocolate() {

// TODO Auto-generated constructor stub

cout<<"Chocolate is made..."<<endl;


}


Chocolate::~Chocolate() {

// TODO Auto-generated destructor stub

}


string Chocolate::getName(){

return "It's a Chocolate";

}



/*

* Biscuit.h

*

* Created on: Mar 10, 2021

* Author: som

*/


#ifndef BISCUIT_H_

#define BISCUIT_H_


#include "Food.h"


class Biscuit: public Food {

public:

Biscuit();

string getName();

~Biscuit();

};


#endif /* BISCUIT_H_ */



/*

* Biscuit.cpp

*

* Created on: Mar 10, 2021

* Author: som

*/

#include <iostream>

#include "Biscuit.h"

using namespace std;



Biscuit::Biscuit() {

// TODO Auto-generated constructor stub

cout<<"Biscuit is made..."<<endl;


}


Biscuit::~Biscuit(){}



string Biscuit::getName(){

return "It's a Biscuit";

}




/*

* Factory.h

*

* Created on: Mar 10, 2021

* Author: som

*/


#ifndef FACTORY_H_

#define FACTORY_H_


#include <boost/python.hpp>

#include <iostream>

#include <string>


#include "Biscuit.h"

#include "Chocolate.h"


using namespace std;


class Factory{

public:

static Factory* instance;

static Factory* getInstance();


Food* makeFood(const string& type);


private:

Factory(){}


// Delete copy constructor & assignment operator (Singleton pattern)

Factory(const Factory&) = delete;

Factory& operator=(const Factory&) = delete;

};




#endif /* FACTORY_H_ */




/*

* Factory.cpp

*

* Created on: Jan 30, 2025

* Author: som

*/

#include "Factory.h"

Factory* Factory::instance = NULL;


Factory* Factory:: getInstance(){

if(Factory::instance == NULL){

Factory::instance = new Factory();

}

return Factory::instance;

}


Food* Factory::makeFood(const string& type){

if(type.compare("bi") == 0){

return new Biscuit();

}

if(type.compare("ch") == 0){

return new Chocolate();

}


return NULL;

}


// Expose Singleton Factory to Python

BOOST_PYTHON_MODULE(FactoryPattern) {

using namespace boost::python;


class_<Food, boost::noncopyable>("Food", no_init)

.def("getName", pure_virtual(&Food::getName));


class_<Biscuit, bases<Food>>("Biscuit")

.def("getName", &Biscuit::getName); // Ensure Biscuit has getName


class_<Chocolate, bases<Food>>("Chocolate")

.def("getName", &Chocolate::getName); // Ensure Chocolate has getName


class_<Factory, boost::noncopyable>("Factory", no_init)

.def("getInstance", &Factory::getInstance, return_value_policy<reference_existing_object>())

.staticmethod("getInstance")

.def("makeFood", &Factory::makeFood, return_value_policy<manage_new_object>());

}


Here's the project settings for the C++ code...








And here's the python script to access the C++ methods.


import FactoryPattern

factory = FactoryPattern.Factory.getInstance()

biscuit = factory.makeFood("bi")
print(biscuit.getName()) # Expected: "Biscuit"

chocolate = factory.makeFood("ch")
print(chocolate.getName()) # Expected: "Chocolate"


Here's a short video showing the output in a Python workspace...



Jai Hind... Jai Bharat...

By the way... there is another way to connect your Python code

to C++ - that is SWIG...


I explored SWIG sometimes back.


Here we go...