Skip to content
Snippets Groups Projects
GamsLandUseOptimiser.java 5.27 KiB
Newer Older
Peter Alexander's avatar
Peter Alexander committed
package ac.ed.lurg.country.gams;

import java.io.File;
import java.util.Map;

import ac.ed.lurg.ModelConfig;
import ac.ed.lurg.types.Item;
import ac.ed.lurg.types.LandCoverType;
import ac.ed.lurg.utils.LogWriter;

import com.gams.api.GAMSDatabase;
import com.gams.api.GAMSGlobals;
import com.gams.api.GAMSJob;
import com.gams.api.GAMSOptions;
import com.gams.api.GAMSParameter;
import com.gams.api.GAMSVariable;
import com.gams.api.GAMSVariableRecord;
import com.gams.api.GAMSWorkspace;
import com.gams.api.GAMSWorkspaceInfo;

public class GamsLandUseOptimiser {
	
	private GamsLandUseData inputData;
	
	public GamsLandUseOptimiser(GamsLandUseData inputData) {
		this.inputData = inputData;
	}
	
	public void run() {

		File workingDirectory = new File(ModelConfig.TEMP_DIR, "GamsTest");
		workingDirectory.mkdir();

		GAMSWorkspaceInfo  wsInfo  = new GAMSWorkspaceInfo();
		wsInfo.setWorkingDirectory(workingDirectory.getAbsolutePath());
	//	wsInfo.setDebugLevel(DebugLevel.VERBOSE);
		
		GAMSWorkspace ws = new GAMSWorkspace(wsInfo);
		GAMSDatabase db = ws.addDatabase();

		GAMSParameter parm = db.addParameter("previous_area", 1, "the previous area for each land use");
		addLandUseArea(parm, LandCoverType.ARABLE);
		addLandUseArea(parm, LandCoverType.PASTURE);

		LogWriter.println("\nDemand");
		parm = db.addParameter("demand", 1, "demand for crop");
		addItemMapParm(parm, inputData.getProjectedDemand());

		LogWriter.println("\nYield");
		parm = db.addParameter("yield_ref", 1, "ref yield t per ha");
		addItemMapParm(parm, inputData.getRefYield());

		LogWriter.println("\nWorld input energy");
		parm = db.addParameter("world_input_energy", 1, "average input energy from world exports used to determine if we should import or export energy per t");
		addItemMapParm(parm, inputData.getWorldInputEnergy());
		
		LogWriter.println("\nMax Export");
		parm = db.addParameter("maxExport", 1, "max export for each crop based on world market");
		addItemMapParm(parm, inputData.getMaxExport());
		
		addScalar(db.addParameter("meatEfficency", 0, "efficency of converting feed and pasture into animal products"), inputData.getMeatEfficiency());
		addScalar(db.addParameter("maxLandUseChange", 0, "max rate of land use change"), inputData.getMaxLandUseChange());
		addScalar(db.addParameter("maxIntensity", 0, "max intensity which will rise over time"), inputData.getMaxIntensity());
		addScalar(db.addParameter("tradeBarrier", 0, "trade barrier which adjust energy cost of imports"), inputData.getTradeBarrier());
		addScalar(db.addParameter("landChangeEnergy", 0, "energy required to add ha of agricultural land"), inputData.getLandChangeEnergy());
		addScalar(db.addParameter("minFeedRate", 0, "minimum rate of feed for producing animal products"), inputData.getMinFeedRate());

		GAMSJob gamsJob = ws.addJobFromFile(ModelConfig.GAMS_MODEL);
		GAMSOptions opt = ws.addOptions();
		opt.defines("gdxincname", db.getName());
		gamsJob.run(opt, db);
		
        System.out.println(
                "Modelstatus: " + GAMSGlobals.ModelStat.lookup( (int) gamsJob.OutDB().getParameter("ms").findRecord().getValue() ) +
                ", Solvestatus: " + GAMSGlobals.SolveStat.lookup((int) gamsJob.OutDB().getParameter("ss").findRecord().getValue()) );
		
		GAMSVariable varAreas = gamsJob.OutDB().getVariable("area");
		GAMSVariable varIntensities = gamsJob.OutDB().getVariable("intensity");
		GAMSVariable varFeedAmount = gamsJob.OutDB().getVariable("feedAmount");
		GAMSVariable varExports = gamsJob.OutDB().getVariable("exportAmount");
		GAMSVariable varImports = gamsJob.OutDB().getVariable("importAmount");

		double totalArea = 0;
		
		for (GAMSVariableRecord rec : varAreas) {
			LogWriter.println(String.format("%15s:\tarea= %.1f,\tintensity= %.3f,\tfeedAmount= %.0f,\texports= %.0f,\timports= %.0f", 
					rec.getKeys()[0], rec.getLevel(), 
					varIntensities.findRecord(rec.getKeys()[0]).getLevel(), 
					varFeedAmount.findRecord(rec.getKeys()[0]).getLevel(),
					varExports.findRecord(rec.getKeys()[0]).getLevel(),
					varImports.findRecord(rec.getKeys()[0]).getLevel()
					)); 
			totalArea += rec.getLevel();
			// + " marginal=" + rec.getMarginal());
		}
		LogWriter.println(String.format("         Total area= %.1f", totalArea));
		//cleanup(ws.workingDirectory());
	}

	private void addLandUseArea(GAMSParameter parm, LandCoverType landCover) {
		double val = inputData.getLandCoverArea(landCover);
		LogWriter.println("      " + landCover.getId() + ",\t\t" + val);
		parm.addRecord(landCover.getId()).setValue(val);
	}

	private void addScalar(GAMSParameter param, double val) {
		param.addRecord().setValue(val);
	}

	private void addItemMapParm(GAMSParameter parm, Map<Item, Double> itemMap) {
		for (Map.Entry<Item, Double> entry : itemMap.entrySet()) {
			LogWriter.println("      " + entry.getKey().getGamsName() + ",\t\t" + entry.getValue());
			parm.addRecord(entry.getKey().getGamsName()).setValue(entry.getValue());
		}
	}
	
	@SuppressWarnings("unused")
	private void cleanup(String directory)  {
		File directoryToDelete = new File(directory);
		String files[] = directoryToDelete.list();
		for (String file : files) {
			File fileToDelete = new File(directoryToDelete, file);
			try {
				fileToDelete.delete();
			} catch(Exception e){
				e.printStackTrace();
			}
		}
		try {
			directoryToDelete.delete();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

}