void ShortAxisFitting::setThetaDelta(ShortAxisOptimizationInput* input, const alglib::real_1d_array& x) {
	Cmiss_field_module_id field_module = (input->field_module);
	std::vector<Cmiss_node_id>& cmiss_nodes(*(input->cmiss_nodes));
	Cmiss_field_id coordinate = (input->coordinates_rc);
	Cmiss_field_cache_id cache = (input->cache);
	double* initialSegmentLengths = input->initialSegmentLengths;
	int* saxNodes = input->saxNodes;
	int numberOfModelFrames = input->numberOfModelFrames;
	int NUMBER_OF_SEGMENTS = input->NUMBER_OF_SEGMENTS;
	int NUMBER_OF_SAX_NODES = input->NUMBER_OF_SAX_NODES;
	double** result = input->result; //This is expected to be preallocated for heap efficiency
	int* endoNodeIds = input->endoNodesIds;
	const int NUMBER_OF_ENDO_NODES = 48; //Ignore the apex
	int ctr = 0;
	double coord[3];
	int frame = input->frame;
	Point3D centroids[4];
	centroids[0] = input->centroids[0];
	centroids[1] = input->centroids[1];
	centroids[2] = input->centroids[2];
	centroids[3] = input->centroids[3];


	//First 12 endo nodes saxcentroid 0, next 12 1...

	//Set the theta variation in x to the mesh
	{
		Cmiss_field_module_begin_change(field_module);
		{
			double time = ((double) frame) / ((double) numberOfModelFrames);
			if (frame == (numberOfModelFrames - 1))
			{
				time = 1.0;
			}
			Cmiss_field_cache_set_time(cache, time);


			for (int nc = 0; nc < NUMBER_OF_ENDO_NODES; nc++)
			{
				ctr = nc/12;
				double deltaTheta = ((int)(x[ctr]*100000))/100000.0;
				Cmiss_field_cache_set_node(cache, cmiss_nodes[endoNodeIds[nc] - 1]);
				Cmiss_field_evaluate_real(coordinate, cache, 3, coord);
				Point3D start(coord);
				start = start + centroids[nc/12];
				double nTheta = atan2(start.z, start.x) + deltaTheta;
				double dist = sqrt(start.x * start.x + start.z * start.z);
				coord[0] = dist * cos(nTheta) - centroids[nc/12].x;
				coord[2] = dist * sin(nTheta) - centroids[nc/12].z;

				Cmiss_field_assign_real(coordinate, cache, 3, coord);
			}
		}
		Cmiss_field_module_end_change(field_module);
	}

}
Exemple #2
0
void StrainMeasures::embedStrainOnElements(std::string fieldname, std::vector<std::string>& strain) {

	const unsigned int num_strains = numberOfModelFrames_;
	double times[1024];
	for (unsigned int j = 0; j < num_strains; j++) {
		times[j] = static_cast<double>(j) / (num_strains - 1.0);
	}
	Cmiss_time_sequence_id time_sequence = Cmiss_field_module_get_matching_time_sequence(field_module, num_strains, times);

	Cmiss_field_module_begin_change(field_module);

	//Create Node template
	Cmiss_nodeset_id nodeset = Cmiss_field_module_find_nodeset_by_name(field_module, "cmiss_nodes");
	Cmiss_node_template_id nodeTemplate = Cmiss_nodeset_create_node_template(nodeset);
	//Create the field
	Cmiss_field_id strainField = Cmiss_field_module_create_field(field_module, fieldname.c_str(), "finite number_of_components 1 component_names value");
	if (!strainField) {
		std::cout << "Unable to create field " << fieldname << std::endl;
		return;
	}

	Cmiss_node_template_define_field(nodeTemplate, strainField);
	Cmiss_node_template_define_time_sequence(nodeTemplate, strainField, time_sequence);

	//Create Element template
	Cmiss_mesh_id mesh = Cmiss_field_module_find_mesh_by_dimension(field_module, 3);
	Cmiss_element_template_id element_template = Cmiss_mesh_create_element_template(mesh);
	Cmiss_element_template_set_shape_type(element_template, CMISS_ELEMENT_SHAPE_CUBE);
	Cmiss_element_template_set_number_of_nodes(element_template, 1);
	Cmiss_element_basis_id constant_basis = Cmiss_field_module_create_element_basis(field_module, 3, CMISS_BASIS_FUNCTION_CONSTANT);
	const int local_node_index = 1;
	Cmiss_element_template_define_field_simple_nodal(element_template, strainField, -1, constant_basis, 1, &local_node_index);
	Cmiss_element_basis_destroy(&constant_basis);

	//Map strains to elements

	std::map<int, int> elemStrainMap; //Cmiss element no is mapped to strain array number
	//APLAX
	elemStrainMap[3] = elemStrainMap[10] = 1; //Array id base 0
	elemStrainMap[15] = elemStrainMap[22] = 18; //Average of strain ids 2 and 8
	elemStrainMap[27] = elemStrainMap[34] = 12;
	elemStrainMap[39] = elemStrainMap[46] = 17;
	elemStrainMap[40] = elemStrainMap[45] = 17;
	elemStrainMap[28] = elemStrainMap[33] = 10;
	elemStrainMap[16] = elemStrainMap[21] = 19; //Average of strain ids 11 and 5
	elemStrainMap[4] = elemStrainMap[9] = 4;

	//TCH
	elemStrainMap[11] = elemStrainMap[12] = 2; //Array id base 0
	elemStrainMap[23] = elemStrainMap[24] = 20; //Average of strain ids 3 and 9
	elemStrainMap[35] = elemStrainMap[36] = 8;
	elemStrainMap[47] = elemStrainMap[48] = 16;
	elemStrainMap[41] = elemStrainMap[42] = 16;
	elemStrainMap[17] = elemStrainMap[18] = 11;
	elemStrainMap[29] = elemStrainMap[30] = 21; //Average of strain ids 12 and 6
	elemStrainMap[5] = elemStrainMap[6] = 5;

	//FCH
	elemStrainMap[1] = elemStrainMap[2] = 3; //Array id base 0
	elemStrainMap[13] = elemStrainMap[14] = 22; //Average of 10 and 4
	elemStrainMap[25] = elemStrainMap[26] = 4;
	elemStrainMap[37] = elemStrainMap[38] = 23; //Average of strains 14 and 15
	elemStrainMap[43] = elemStrainMap[44] = 24; //Average of strains 16 and 13
	elemStrainMap[31] = elemStrainMap[32] = 6;
	elemStrainMap[19] = elemStrainMap[20] = 25; //Average of strains 7 and 1
	elemStrainMap[7] = elemStrainMap[8] = 0;

	std::vector<std::string> allStrain = strain;

	//Add the additional strains 18 - 23
	std::string s2 = strain[1];
	std::string s8 = strain[7];

	std::string s11 = strain[10];
	std::string s5 = strain[5];

	std::string s9 = strain[8];
	std::string s3 = strain[2];

	std::string s12 = strain[11];
	std::string s6 = strain[6];

	std::string s10 = strain[9];
	std::string s4 = strain[3];

	std::string s14 = strain[13];
	std::string s15 = strain[14];

	std::string s16 = strain[15];
	std::string s13 = strain[12];

	std::string s1 = strain[0];
	std::string s7 = strain[6];

	std::vector<std::string> compute;
	compute.push_back(s2);
	compute.push_back(s8);

	compute.push_back(s11);
	compute.push_back(s5);

	compute.push_back(s9);
	compute.push_back(s3);

	compute.push_back(s12);
	compute.push_back(s6);

	compute.push_back(s10);
	compute.push_back(s4);

	compute.push_back(s14);
	compute.push_back(s15);

	compute.push_back(s16);
	compute.push_back(s13);

	compute.push_back(s7);
	compute.push_back(s1);

	for (int cptc = 0; cptc < 16; cptc += 2) {
		std::vector<std::string> strain1;
		std::vector<std::string> strain2;
		std::ostringstream ss;
		boost::split(strain1, compute[cptc], boost::is_any_of(","));
		boost::split(strain2, compute[cptc + 1], boost::is_any_of(","));
		for (unsigned int j = 0; j < num_strains - 1; j++) {
			double value1 = atof(strain1[j].c_str());
			double value2 = atof(strain2[j].c_str());
			ss << (value1 + value2) * 0.5 << ",";
		}
		ss << "0.0";
		allStrain.push_back(ss.str());
	}

	for (unsigned int i = 0; i < num_elements; i++) {
		Cmiss_node_id temporaryNode = Cmiss_nodeset_create_node(nodeset, extraNodeStartID++, nodeTemplate);
		Cmiss_element_template_set_node(element_template, 1, temporaryNode); //Link node with the element
		Cmiss_element_merge(elements[i], element_template);
		Cmiss_field_cache_set_node(fieldCache, temporaryNode);
		std::vector<std::string> strains;
		boost::split(strains, allStrain[elemStrainMap[i + 1]], boost::is_any_of(","));
		for (unsigned int j = 0; j < num_strains; j++) {
			double value = atof(strains[j].c_str());
			double time = times[j];
			Cmiss_field_cache_set_time(fieldCache, time);
			Cmiss_field_assign_real(strainField,fieldCache,1,&value);
		}
		Cmiss_node_destroy(&temporaryNode);
	}

	Cmiss_field_module_end_change(field_module);
	Cmiss_field_destroy(&strainField);
	Cmiss_element_template_destroy(&element_template);
	Cmiss_node_template_destroy(&nodeTemplate);
	Cmiss_nodeset_destroy(&nodeset);
	//Calling the following leads to the error ERROR: DESTROY(FE_time_sequence).  Positive access_count
	//Cmiss_time_sequence_destroy(&time_sequence);

}
void ShortAxisFitting::optimize(const alglib::real_1d_array& x, double& func, void* ptr) {
	struct ShortAxisOptimizationInput* input = static_cast<struct ShortAxisOptimizationInput*>(ptr);
	Cmiss_field_module_id field_module = (input->field_module);
	std::vector<Cmiss_node_id>& cmiss_nodes(*(input->cmiss_nodes));
	std::vector<double>& targetDeltas(*(input->targetDeltas));
	Cmiss_field_id coordinate = (input->coordinates_rc);
	Cmiss_field_cache_id cache = (input->cache);
	double* initialSegmentLengths = input->initialSegmentLengths;
	int* saxNodes = input->saxNodes;
	int numberOfModelFrames = input->numberOfModelFrames;
	int NUMBER_OF_SEGMENTS = input->NUMBER_OF_SEGMENTS;
	int NUMBER_OF_SAX_NODES = input->NUMBER_OF_SAX_NODES;
	double** result = input->result; //This is expected to be preallocated for heap efficiency
	int* endoNodeIds = input->endoNodesIds;
	const int NUMBER_OF_ENDO_NODES = 48; //Ignore the apex
	int ctr = 0;
	double coord[3];
	int frame = input->frame;
	std::vector<Point3D>& resetCoord(input->initEndoCoordinates->at(frame));
	std::vector<Point3D>& initFrame(*input->initFrame);

	setThetaDelta(input, x);

	//Compute the theta error
	double thetaError = 0.0;
	//for (int frame = 0; frame < numberOfModelFrames; frame++)
	{
		double time = ((double) frame) / ((double) numberOfModelFrames);
		if (frame == (numberOfModelFrames - 1))
		{
			time = 1.0;
		}
		Cmiss_field_cache_set_time(cache, time);
		std::vector<Point3D> sax;
		Point3D sax_centroid(0, 0, 0);
		for (int seg = 0; seg < NUMBER_OF_SAX_NODES; seg++)
		{
			Cmiss_field_cache_set_node(cache, cmiss_nodes[saxNodes[seg]]);
			Cmiss_field_evaluate_real(coordinate, cache, 3, coord);
			Point3D start(coord);
			sax.push_back(start);
			sax_centroid += start;
		}
		sax_centroid = sax_centroid * (1.0 / NUMBER_OF_SAX_NODES);
		double avg = 0.0;
		for (int seg = 0; seg < NUMBER_OF_SAX_NODES; seg++)
		{
			Vector3D trans = sax[seg] - sax_centroid;
			double denom = trans.x- initFrame[seg].x;
			double nuem  = trans.z- initFrame[seg].z;
			double ltheta = atan2(nuem, denom);
			if(fabs(denom)<1.0e-6 && fabs(nuem)<1.0e-6){
					ltheta = 0.0;
			}
			avg += ltheta;
		}
		avg /=NUMBER_OF_SAX_NODES;
		thetaError +=fabs(avg-targetDeltas[frame]);
		input->thetaError = avg;
	}


	//Compute the segment error
	getSegmentLengths(input);
	double segmentMatchError = input->segmentMatchError;
	func = segmentMatchError + thetaError;
	if(segmentMatchError>2.0)
		func = 1.0e+30;
	input->totalError = func;
	//Reset coordinates to original
	{
		Cmiss_field_module_begin_change(field_module);

		{
			double time = ((double) frame) / ((double) numberOfModelFrames);
			if (frame == (numberOfModelFrames - 1))
			{
				time = 1.0;
			}
			Cmiss_field_cache_set_time(cache, time);
			for (int nc = 0; nc < NUMBER_OF_ENDO_NODES; nc++)
			{
				coord[0] = resetCoord[nc].x;
				coord[1] = resetCoord[nc].y;
				coord[2] = resetCoord[nc].z;
				Cmiss_field_cache_set_node(cache, cmiss_nodes[endoNodeIds[nc] - 1]);
				Cmiss_field_assign_real(coordinate, cache, 3, coord);
			}
		}
		Cmiss_field_module_end_change(field_module);
	}
}
Exemple #4
0
inline int Field::assignReal(FieldCache& cache,	int numberOfValues, const double *values)
{
	return Cmiss_field_assign_real(id, cache.getId(), numberOfValues,
		values);
}