Commit dea86173 authored by Giovanni La Mura's avatar Giovanni La Mura
Browse files

Initiate porting of cluster to C++

parent 7ad971ab
Loading
Loading
Loading
Loading
+279 −0
Original line number Diff line number Diff line
#include <cstdio>
#include <fstream>
#include <string>
#include <complex>
#ifndef INCLUDE_CONFIGURATION_H_
#include "../include/Configuration.h"
#endif
#ifndef INCLUDE_CLU_SUBS_H_
#include "../include/clu_subs.h"
#endif

using namespace std;

/*
 * >>> WARNING: works only for IDFC >= 0, as the original code <<<
 *
 */

//! \brief C++ implementation of CLU
void cluster() {
	printf("INFO: making legacy configuration ...\n");
	ScattererConfiguration *conf = ScattererConfiguration::from_dedfb("DEDFB_clu");
	conf->write_formatted("c_OEDFB_clu");
	conf->write_binary("c_TEDF_clu");
	delete conf;
	printf("INFO: reading binary configuration ...\n");
	ScattererConfiguration *sconf = ScattererConfiguration::from_binary("c_TEDF_clu");
	GeometryConfiguration *gconf = GeometryConfiguration::from_legacy("DCLU");
	if (sconf->number_of_spheres == gconf->number_of_spheres) {
		// Shortcuts to variables stored in configuration objects
		int nsph = gconf->number_of_spheres;
		int mxndm = gconf->mxndm;
		int inpol = gconf->in_pol;
		int npnt = gconf->npnt;
		int npntts = gconf->npntts;
		int iavm = gconf->iavm;
		int isam = gconf->meridional_type;
		int nxi = sconf->number_of_scales;
		double th = gconf->in_theta_start;
		double thstp = gconf->in_theta_step;
		double thlst = gconf->in_theta_end;
		double ths = gconf->sc_theta_start;
		double thsstp = gconf->sc_theta_step;
		double thslst = gconf->sc_theta_end;
		double ph = gconf->in_phi_start;
		double phstp = gconf->in_phi_step;
		double phlst = gconf->in_phi_end;
		double phs = gconf->sc_phi_start;
		double phsstp = gconf->sc_phi_step;
		double phslst = gconf->sc_phi_end;
		double wp = sconf->wp;
		// Global variables for CLU
		double pi = 2.0 * acos(0.0);
		int lm = gconf->l_max;
		if (gconf->li > lm) lm = gconf->li;
		if (gconf->le > lm) lm = gconf->le;
		C1 *c1 = new C1(nsph, lm, sconf->nshl_vec, sconf->iog_vec);
		C3 *c3 = new C3();
		for (int c1i = 0; c1i < nsph; c1i++) {
			c1->rxx[c1i] = gconf->sph_x[c1i];
			c1->ryy[c1i] = gconf->sph_y[c1i];
			c1->rzz[c1i] = gconf->sph_z[c1i];
			c1->ros[c1i] = sconf->radii_of_spheres[c1i];
			int iogi = c1->iog[c1i];
			if (iogi >= c1i + 1) {
				double gcss = pi * c1->ros[c1i] * c1->ros[c1i];
				c1->gcsv[c1i] = gcss;
				int nsh = c1->nshl[c1i];
				for (int j16 = 1; j16 <= nsh; j16++) {
					c1->rc[c1i][j16- 1] = sconf->rcf[c1i][j16] * c1->ros[c1i];
				}
				c3->gcs += c1->gcsv[c1i - 1];
			}
		}
		C4 *c4 = new C4;
		c4->li = gconf->li;
		c4->le = gconf->le;
		c4->lm = lm;
		c4->lmpo = c4->lm + 1;
		c4->litpo = 2 * gconf->li + 1;
		c4->litpos = c4->litpo * c4->litpo;
		c4->lmtpo = gconf->li + gconf->le + 1;
		c4->lmtpos = c4->lmtpo * c4->lmtpo;
		c4->nlim = c4->li * (c4->li + 2);
		c4->nlem = c4->le * (c4->le + 2);
		c4->nsph = nsph;
		C6 *c6 = new C6(c4->lmtpo);
		C1_AddOns *c1ao = new C1_AddOns(c4);
		FILE *output = fopen("c_OCLU", "w");
		double ****zpv = new double***[c4->lm];
		for (int zi = 0; zi < c4->lm; zi++) {
			zpv[zi] = new double**[3];
			for (int zj = 0; zj < 3; zj++) {
				zpv[zi][zj] = new double*[2];
				zpv[zi][zj][0] = new double[2];
				zpv[zi][zj][1] = new double[2];
			}
		}
		int jer = 0, lcalc = 0;
		complex<double> arg = complex<double>(0.0, 0.0);
		int max_ici = 0;
		for (int insh = 0; insh < nsph; insh++) {
			int nsh = sconf->nshl_vec[insh];
			int ici = (nsh + 1) / 2;
			if (ici > max_ici) max_ici = ici;
		}
		C2 *c2 = new C2(nsph, max_ici, npnt, npntts);
		complex<double> **am = new complex<double>*[mxndm];
		for (int ai = 0; ai < mxndm; ai++) am[ai] = new complex<double>[mxndm];
		// End of global variables for CLU
		fprintf(output, " READ(IR,*)NSPH,LI,LE,MXNDM,INPOL,NPNT,NPNTTS,IAVM,ISAM\n");
		fprintf(output, " %5d%5d%5d%5d%5d%5d%5d%5d%5d\n",
				nsph, c4->li, c4->le, mxndm, inpol, npnt, npntts, iavm, isam
		);
		fprintf(output, " READ(IR,*)RXX(I),RYY(I),RZZ(I)\n");
		for (int ri = 0; ri < nsph; ri++) fprintf(output, "%17.8lE%17.8lE%17.8lE\n",
				gconf->sph_x[ri], gconf->sph_y[ri], gconf->sph_z[ri]
		);
		fprintf(output, " READ(IR,*)TH,THSTP,THLST,THS,THSSTP,THSLST\n");
		fprintf(
				output, " %10.3lE%10.3lE%10.3lE%10.3lE%10.3lE%10.3lE\n",
				th, thstp, thlst, ths, thsstp, thslst
		);
		fprintf(output, " READ(IR,*)PH,PHSTP,PHLST,PHS,PHSSTP,PHSLST\n");
		fprintf(
				output, " %10.3lE%10.3lE%10.3lE%10.3lE%10.3lE%10.3lE\n",
				ph, phstp, phlst, phs, phsstp, phslst
		);
		fprintf(output, "  READ(IR,*)JWTM\n");
		fprintf(output, " %5d\n", gconf->jwtm);
		fprintf(output, "  READ(ITIN)NSPHT\n");
		fprintf(output, "  READ(ITIN)(IOG(I),I=1,NSPH)\n");
		fprintf(output, "  READ(ITIN)EXDC,WP,XIP,IDFC,NXI\n");
		fprintf(output, "  READ(ITIN)(XIV(I),I=1,NXI)\n");
		fprintf(output, "  READ(ITIN)NSHL(I),ROS(I)\n");
		fprintf(output, "  READ(ITIN)(RCF(I,NS),NS=1,NSH)\n");
		fprintf(output, " \n");
		double small = 1.0e-3;
		int nth = 0, nph = 0;
		if (thstp != 0.0) nth = int((thlst - th) / thstp + small);
		nth++;
		if (phstp != 0.0) nph = int((phlst - ph) / phstp + small);
		nph++;
		int nths = 0, nphs = 0;
		double thsca = 0.0;
		if (isam > 1) {
			nths = 1;
			thsca = ths - th;
		} else { // ISAM <= 1
			if (thsstp == 0.0) nths = 0;
			else nths = int ((thslst - ths) / thsstp + small);
			nths++;
		}
		if (isam >= 1) {
			nphs = 1;
		} else {
			if (phsstp == 0.0) nphs = 0;
			else nphs = int((phslst - phs) / phsstp + small);
			nphs++;
		}
		int nk = nth * nph;
		int nks = nths * nphs;
		int nkks = nk * nks;
		double th1 = th, ph1 = ph, ths1 = ths, phs1 = phs;
		str(c1, c1ao, c3, c4, c6);
		thdps(c4->lm, zpv);
		double exri = sqrt(sconf->exdc);
		double vk = 0.0; // NOTE: Not really sure it should be initialized at 0
		fprintf(output, "  REFR. INDEX OF EXTERNAL MEDIUM=%15.7lE\n", exri);
		fstream tppoan;
		tppoan.open("c_TPPOAN", ios::out | ios::binary);
		if (tppoan.is_open()) {
			tppoan.write(reinterpret_cast<char *>(&iavm), sizeof(int));
			tppoan.write(reinterpret_cast<char *>(&isam), sizeof(int));
			tppoan.write(reinterpret_cast<char *>(&inpol), sizeof(int));
			tppoan.write(reinterpret_cast<char *>(&nxi), sizeof(int));
			tppoan.write(reinterpret_cast<char *>(&nth), sizeof(int));
			tppoan.write(reinterpret_cast<char *>(&nph), sizeof(int));
			tppoan.write(reinterpret_cast<char *>(&nths), sizeof(int));
			tppoan.write(reinterpret_cast<char *>(&nphs), sizeof(int));
			int nlemt = c4->nlem + c4->nlem;
			double wn = wp / 3.0e8;
			double sqsfi = 1.0;
			if (sconf->idfc < 0) {
				vk = sconf->xip * wn;
				fprintf(output, "  VK=%15.7lE, XI IS SCALE FACTOR FOR LENGTHS\n", vk);
				fprintf(output, "  \n");
			}
			for (int jxi488 = 1; jxi488 <= nxi; jxi488++) {
				int jaw = 1;
				fprintf(output, "========== JXI =%3d ====================\n", jxi488);
				double xi = sconf->scale_vec[jxi488 - 1];
				double vkarg = 0.0;
				if (sconf->idfc >= 0) {
					vk = xi * wn;
					vkarg = vk;
					fprintf(output, "  VK=%15.7lE, XI=%15.7lE\n", vk, xi);
				} else {
					vkarg = xi * vk;
					sqsfi = 1.0 / (xi * xi);
					fprintf(output, "  XI=%15.7lE\n", xi);
				}
				// Would call HJV(EXRI, VKARG, JER, LCALC, ARG)
				hjv(exri, vkarg, jer, lcalc, arg, c1, c1ao, c4);
				//printf("INFO: calculation went up to %d and jer = %d\n", lcalc, jer);
				//printf("INFO: arg = (%lE,%lE)\n", arg.real(), arg.imag());
				if (jer != 0) {
					fprintf(output, "  STOP IN HJV\n");
					break; // jxi488 loop: goes to memory cleaning and  return
				}
				for (int i132 = 1; i132 <= nsph; i132++) {
					int iogi = c1->iog[i132 - 1];
					if (iogi != i132) {
						for (int l123 = 1; l123 <= gconf->li; l123++) {
							c1->rmi[l123 - 1][i132 - 1] = c1->rmi[l123 - 1][iogi - 1];
							c1->rei[l123 - 1][i132 - 1] = c1->rei[l123 - 1][iogi - 1];
						} // l123 loop
					} else {
						int nsh = sconf->nshl_vec[i132 - 1];
						int ici = (nsh + 1) / 2;
						int size_dc0 = (nsh % 2 == 0) ? ici + 1 : ici;
						if (sconf->idfc == 0) {
							for (int ic = 0; ic < ici; ic++)
								c2->dc0[ic] = sconf->dc0_matrix[ic][i132 - 1][jxi488 - 1];
						} else {
							if (jxi488 == 1) {
								for (int ic = 0; ic < ici; ic++)
									c2->dc0[ic] = sconf->dc0_matrix[ic][i132 - 1][0];
							}
						}
						if (nsh % 2 == 0) c2->dc0[ici] = sconf->exdc;
						dme(
								c4->li, i132, npnt, npntts, vkarg, sconf->exdc, exri,
								c1, c2, jer, lcalc, arg
						);
						//printf("INFO: DME returned jer = %d , lcalc = %d and arg = (%lE, %lE)\n",
						//		jer, lcalc, arg.real(), arg.imag());
						if (jer != 0) {
							fprintf(output, "  STOP IN DME\n");
							break;
						}
					}
					if (jer != 0) break;
				} // i132 loop
				// Would call CMS(AM)

				if (jer != 0) break;
			} // jxi488 loop
			tppoan.close();
		} else { // In case TPPOAN could not be opened. Should never happen.
			printf("ERROR: failed to open TPPOAN file.\n");
		}
		fclose(output);
		// Clean memory
		delete c1;
		delete c1ao;
		delete c3;
		delete c4;
		delete c6;
		for (int zi = c4->lm - 1; zi > -1; zi--) {
			for (int zj = 2; zj > -1; zj--) {
				delete[] zpv[zi][zj][1];
				delete[] zpv[zi][zj][0];
				delete[] zpv[zi][zj];
			}
			delete[] zpv[zi];
		}
		delete[] zpv;
		for (int ai = mxndm - 1; ai > -1; ai--) delete[] am[ai];
		delete[] am;
	} else { // NSPH mismatch between geometry and scatterer configurations.
		throw UnrecognizedConfigurationException(
				"Inconsistent geometry and scatterer configurations."
		);
	}
	delete sconf;
	delete gconf;
	printf("Done.\n");
}

src/include/clu_subs.h

0 → 100644
+740 −0

File added.

Preview size limit exceeded, changes collapsed.